The posters here say that Date is always in UTC time. However, if I create a Date(), create a Calendar, and set the calendar time with the date, the time remains my local time (and I am not on UTC time.
I've tested this by printing out the calendar's date in a loop, subtracting an hour per loop. It's 11pm on the 19th of May here, and it takes 24 loops before the date changes to the 18th of May. It's currently 1pm UTC, so if the calendar were set properly it would only take 14 loops.
Date date = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd");
int index = 0;
for(; index > -30; index--)
{
System.out.println(index);
System.out.println(dateFormatter.format(calendar.getTime()));
System.out.println();
calendar.add(Calendar.HOUR, -1);
}
java.util.Calendar has a static factory method which takes a timezone.
Calendar.getInstance(java.util.TimeZone)
So you can say:
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
Related
When I use these codes, I get dates of the month which we are in. For instance, I can see dates between from 01/09/2017 to 21/09/2017.
private void createRandomData(InMemoryCursor cursor) {
List<Object[]> data = new ArrayList<>();
Calendar today = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
today.set(Calendar.HOUR_OF_DAY,0);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);
today.set(Calendar.MILLISECOND, 0);
mStart = (Calendar) today.clone();
mStart.set(Calendar.DAY_OF_MONTH, 1);
while (mStart.compareTo(today) <= 0) {
data.add(createItem(mStart.getTimeInMillis()));
mStart.add(Calendar.DAY_OF_MONTH, 1);
}
cursor.addAll(data);
}
However, I need dates of the particular month. How can I see other dates which in other months? For example, I want to see dates of April. It should not be September. (I know it's related to today.clone() but I didn't understand how can I change it).
I plan to separate months with dialog in Android studio and when I select any month, I should see all of dates of month.
I need just dates of a month for doing this, like April. How can I get dates of April? (If I get dates of April, I can do this all of the months)
EDIT Some changing and results:
private void createRandomData(InMemoryCursor cursor) {
List<Object[]> data = new ArrayList<>();
Calendar today = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
today.set(Calendar.HOUR_OF_DAY,0);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);
today.set(Calendar.MILLISECOND, 0);
mStart = (Calendar) today.clone();
mStart.set(Calendar.MONTH, Calendar.APRIL);
mStart.set(Calendar.DAY_OF_MONTH, 1);
data.add(createItem(mStart.getTimeInMillis()));
cursor.addAll(data);
}
I get just 01/04/2017
private void createRandomData(InMemoryCursor cursor) {
List<Object[]> data = new ArrayList<>();
Calendar today = Calendar.getInstance(TimeZone.getDefault(), Locale.getDefault());
today.set(Calendar.HOUR_OF_DAY,0);
today.set(Calendar.MINUTE, 0);
today.set(Calendar.SECOND, 0);
today.set(Calendar.MILLISECOND, 0);
mStart = (Calendar) today.clone();
mStart.set(Calendar.MONTH, Calendar.APRIL);
int daysInMonth = today.getActualMaximum(Calendar.DAY_OF_MONTH);
for(int i=0; i<daysInMonth; i++ ){
mStart.set(Calendar.DAY_OF_MONTH, i);}
data.add(createItem(mStart.getTimeInMillis()));
cursor.addAll(data);
}
I get just 29/04/2017 and If I change mStart.set(Calendar.DAY_OF_MONTH, i) to mStart.set(Calendar.DAY_OF_MONTH, 1) result is 01/04/2017
To get all the dates of a particular month, set the Calendar to a date in that month, e.g. the 1th, ask the Calendar for the number of dates in that month, then get the dates.
You could also just get dates until month changes, but code below ask for number of days in the month, to show how you can do that.
This code just prints the dates. You can of course do whatever you want with them instead.
public static void printDatesInMonth(int year, int month) {
SimpleDateFormat fmt = new SimpleDateFormat("dd/MM/yyyy");
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(year, month - 1, 1);
int daysInMonth = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
for (int i = 0; i < daysInMonth; i++) {
System.out.println(fmt.format(cal.getTime()));
cal.add(Calendar.DAY_OF_MONTH, 1);
}
}
Test
printDatesInMonth(2017, 2);
Output
01/02/2017
02/02/2017
03/02/2017
04/02/2017
05/02/2017
06/02/2017
07/02/2017
08/02/2017
09/02/2017
10/02/2017
11/02/2017
12/02/2017
13/02/2017
14/02/2017
15/02/2017
16/02/2017
17/02/2017
18/02/2017
19/02/2017
20/02/2017
21/02/2017
22/02/2017
23/02/2017
24/02/2017
25/02/2017
26/02/2017
27/02/2017
28/02/2017
#Andreas's answer provides the way to do it with Calendar. I just like to add another approach.
The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.
In Android you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. To make it work, you'll also need the ThreeTenABP (more on how to use it here).
First you can use a org.threeten.bp.YearMonth to represent the month and year (in this case, April 2017). Then you loop through all the days of this month.
The getTimeInMillis() method takes the number of milliseconds since epoch (1970-01-01T00:00Z), and in your code you're getting it from the date at midnight, in the JVM default timezone.
In ThreeTen Backport, you do this by converting the YearMonth to a org.threeten.bp.LocalDate, then convert it to the JVM default timezone (using a org.threeten.bp.ZoneId), and then using the resulting org.threeten.bp.ZonedDateTime to get the epoch millis value:
// April 2017
YearMonth ym = YearMonth.of(2017, 4);
// get the last day of month
int lastDay = ym.lengthOfMonth();
// loop through the days
for(int day = 1; day <= lastDay; day++) {
// create the day
LocalDate dt = ym.atDay(day);
// set to midnight at JVM default timezone
ZonedDateTime z = dt.atStartOfDay(ZoneId.systemDefault());
// get epoch millis value
data.add(createItem(z.toInstant().toEpochMilli()));
}
If you also need to check if the date is before the current date, you can add an additional check:
....
// today
LocalDate today = LocalDate.now();
// loop through the days
for (int day = 1; day <= lastDay; day++) {
// create the day
LocalDate dt = ym.atDay(day);
if (dt.isBefore(today)) {
....
The use of TimeZone.getDefault() and ZoneId.systemDefault(), although might seem a good convenience, is also tricky, because the JVM default timezone can be changed without notice, even at runtime, so it's better to always make it explicit which one you're using.
The API uses IANA timezones names (always in the format Region/City, like America/Sao_Paulo or Europe/Berlin).
Avoid using the 3-letter abbreviations (like CST or PST) because they are ambiguous and not standard.
You can get a list of available timezones (and choose the one that fits best your system) by calling ZoneId.getAvailableZoneIds().
Example: to use the New York timezone, you could do:
....
// New York timezone
ZoneId ny = ZoneId.of("America/New_York");
// today in New York timezone
LocalDate today = LocalDate.now(ny);
// loop through the days
for (int day = 1; day <= lastDay; day++) {
// create the day
LocalDate dt = ym.atDay(day);
if (dt.isBefore(today)) {
// set to midnight at New York timezone
ZonedDateTime z = dt.atStartOfDay(ny);
....
America/New_York is one of the valid names returned by ZoneId.getAvailableZoneIds().
java.util.Calendar
Regarding your code, you're starting with day zero and adding the item to data outside of the loop (so you're just adding the last one - indent your code and you'll see that data.add is outside of the for loop). The code should be like that:
Calendar mStart = (Calendar) today.clone();
// set day to 1
mStart.set(Calendar.DAY_OF_MONTH, 1);
// set month to April
mStart.set(Calendar.MONTH, Calendar.APRIL);
// now mStart is April 1st, we can begin the loop
// get the number of days in April
int daysInMonth = today.getActualMaximum(Calendar.DAY_OF_MONTH);
// loop from day 1 to daysInMonth
for (int i = 1; i <= daysInMonth; i++) {
// set the day
mStart.set(Calendar.DAY_OF_MONTH, i);
// add item for the day
data.add(createItem(mStart.getTimeInMillis()));
}
// add all items to cursor
cursor.addAll(data);
you are starting with today's date, so assuming you want months starting from there simply use:
cal.add(Calendar.MONTH, 1) to move to next month or
cal.add(Calendar.MONTH, -1) to move to last month.
Hello guys i have a tricky question for you that i really cant find a solution out there.
What i want to do is to have 3 date/time inputs on simpledateformat
Date 1
Date 2
Date 3
and basicaly i want to get difference of months days hours and minutes from date 1 - date2 and result of those 2 dates to be added on the firth date
for example 11/3/2017 12:30 - 7/3/2017 = 4 days and ADD that to current date 13/3/2017 13:30 + 4 days and 1 hour = 17/3/2017 14:30
i know how to get the diference in days hours and minutes , i cant get the second part of adding the result to the current date
any ideas?
thank you in dvance
Use Calendar class to add days and hours
Calendar cal = Calendar.getInstance();
cal.setTime(yourDate);
cal.add(Calendar.DAY_OF_MONTH, yourDays); //adds days to your date
cal.add(Calendar.HOUR_OF_DAY, yourHours); //adds hours to your date
cal.getTime(); //to get Date instance
To decrement dates just add negative number, for example:
int yourDays = -daysVariable;
int yourHours = -hoursVariable; //
Calendar cal = Calendar.getInstance();
cal.setTime(yourDate);
cal.add(Calendar.DAY_OF_MONTH, yourDays); //decrement days
cal.add(Calendar.HOUR_OF_DAY, yourHours); //decrement hours
cal.getTime(); //to get Date instance
Get a date object using the simpledate format
Because it is an object of the same type
Comparison is possible
I think you need to use getTime and add days throught miliseconds.
For example, if you can get the difference of days you should use something like this
date1.getTime() + 24*60*60*1000*4
(where 4 is the difference you want to add)
You can use Calendar too.
Thank you all for your ultra fast replies!
I solved it by using Mij Solution
Calendar cal = Calendar.getInstance();
cal.setTime(yourDate);
cal.add(Calendar.DAY_OF_MONTH, yourDays); //adds days to your date
cal.add(Calendar.HOUR_OF_DAY, yourHours); //adds hours to your date
cal.getTime(); //to get Date instance
To add days and
tis code to decrese days
Calendar cal = Calendar.getInstance();
cal.setTime(yourDate);
cal.add(Calendar.DAY_OF_MONTH, -yourDays); //adds days to your date
cal.add(Calendar.HOUR_OF_DAY, -yourHours); //adds hours to your date
cal.getTime(); //to get Date instance
and to control if date is bigget than my current date i used this condition
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date strDate = sdf.parse(valid_until);
if (new Date().after(strDate)) {
catalog_outdated = 1;
}
it returns -1 if the date is past from current
+1 if date is bigger that current or whatever
and 0 if dates are equal
again thank you!
I need to set some days in method set. I try to use:
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
c.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
but with this way set only Wednesday.
Thank you and sorry for my english :)
The Calendar does not function as you expect it to. From the JavaDoc:
The Calendar class is an abstract class that provides methods for
converting between a specific instant in time and a set of calendar
fields such as YEAR, MONTH, DAY_OF_MONTH, HOUR, and so on, and for
manipulating the calendar fields, such as getting the date of the next
week. An instant in time can be represented by a millisecond value
that is an offset from the Epoch, January 1, 1970 00:00:00.000 GMT
(Gregorian).
Notice that the documentation states a specific instant in time. This implies the Calendar can only be based off of one point in time from epoch.
When you use the set method you are adjusting the specific instant in time through each call. So first it gets set to Monday then Wednesday.
You could use a List<Calendar> to store multiple Calendar instances set to your desired days.
public class CalendarTest {
public static void main(String[] args) {
Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal1.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
cal2.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
List<Calendar> calendars = Arrays.asList(cal1, cal2);
}
}
public static String getDay(String day,String month,String year){
int mm = Integer.parseInt(month);
int dd = Integer.parseInt(day);
int yy = Integer.parseInt(year);
LocalDate dt = LocalDate.of(yy, mm, dd);
return dt.getDayOfWeek().toString().toUpperCase();
}
I have Integer fields:
currentYear,currentMonth,currentDay,currentHour,currentMinute and nextYear,nextMonth,nextDay,nextHour,nextMinute.
How I can get difference between those two spots in time in milliseconds.
I found a way using Date() object, but those functions seems to be depricated, so it's little risky.
Any other way?
Use GregorianCalendar to create the date, and take the diff as you otherwise would.
GregorianCalendar currentDay=new GregorianCalendar (currentYear,currentMonth,currentDay,currentHour,currentMinute,0);
GregorianCalendar nextDay=new GregorianCalendar (nextYear,nextMonth,nextDay,nextHour,nextMinute,0);
diff_in_ms=nextDay. getTimeInMillis()-currentDay. getTimeInMillis();
Create a Calendar object for currenDay and nextDay, turn them into longs, then subtract. For example:
Calendar currentDate = Calendar.getInstance();
Calendar.set(Calendar.MONTH, currentMonth - 1); // January is 0, Feb is 1, etc.
Calendar.set(Calendar.DATE, currentDay);
// set the year, hour, minute, second, and millisecond
long currentDateInMillis = currentDate.getTimeInMillis();
Calendar nextDate = Calendar.getInstance();
// set the month, date, year, hour, minute, second, and millisecond
long nextDateInMillis = nextDate.getTimeInMillis();
return nextDateInMillis - currentDateInMillis; // this is what you want
If you don't like the confusion around the Calendar class, you can check out the Joda time library.
The time displayed is way ahead of what I expected. I'm parsing a date string and turning it into milliseconds.
year = Integer.parseInt(m1.group(1));
mo = Integer.parseInt(m1.group(2));
day = Integer.parseInt(m1.group(3));
hr = Integer.parseInt(m1.group(4));
min = Integer.parseInt(m1.group(5));
sec = Integer.parseInt(m1.group(6));
and here I set the Calendar
Calendar cal = Calendar.getInstance();
cal.set(year, mo, day, hr, min, sec);
time = cal.getTimeInMillis();
If you check out the calendar documentation here, then visit here, you'll see that January is month 0. You'll want to change your code to mo = Integer.parseInt(m1.group(2))-1;
You should probably use DateFormatter to parse the date string (rather than rolling your own).
Other than that, make sure that you have the proper time zone and understand that month number one is February (not January).