I get from my GPS tracker a time String in UTC-Format like this: hhmmss.ssss.
I want to convert the UTC time to the local time of the user by using calendar. So I extract the hours, minutes and seconds from the time String via substring(int start, int end) and set it via the Calendar.set(int field, int value) function. After this I convert the Calendar to a Date, but know I have a wrong day.
For example timestamp = 091215.0000,
If I log Calendar.getInstance()I get: Thu Dec 11 10:12:15 GMT+01:00 2018
But when I convert it with my function I get: Thu Dec 13 10:12:15 GMT+01:00 2018
My function
public static Date utcToLocalTimeFromLock(String timestamp) {
Calendar calendar = Calendar.getInstance();
if (timestamp.charAt(0) == '0') {
calendar.set(Calendar.HOUR_OF_DAY, timestamp.charAt(1) + 1);
} else {
calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(timestamp.substring(0, 2) + 1));
}
calendar.set(Calendar.MINUTE, Integer.valueOf(timestamp.substring(2, 4)));
calendar.set(Calendar.SECOND, Integer.valueOf(timestamp.substring(4, 6)));
Date date = calendar.getTime();
Log.d(LOG_TAG, "utcToLocalTimeFromLock: " + date);
return date;
}
What went wrong in your code?
Your bug is in this line:
calendar.set(Calendar.HOUR_OF_DAY, timestamp.charAt(1) + 1);
Characters are represented as numbers in computers. It’s a confusing fact of Java that characters and numbers can be used interchangeably in many cases. If timestamp.charAt(1) is the char '9' as in your example, it is represented as the number 57. When you add 1, you get 58. When you set the hour of day to 58 — if you had expected the Calendar class with default settings to report an error, you were wrong, this a confusing thing about that class and just one of the many reasons why we recommend you avoid using it. It just keeps counting hours into the next days and coincidentally ends up at the right hour of day, 10, only two days later (two days is 48 hours, and 48 + 10 = 58).
Other recommendation:
Don’t “hand parse” your time string. Leave parsing to a library class.
Don’t convert to Central European Time by adding an hour. It’s error-prone. During summer time (DST) it will give an incorrect result. It’s not portable to other time zones. Instead again leave the conversion to the library classes.
How to fix?
Basil Bourque already showed the good way to solve your problem using java.time, the modern Java date and time API. I’d like to show you that with java.time you can also include the fraction of second without much trouble if you like, though.
static DateTimeFormatter timeFormatter = new DateTimeFormatterBuilder()
.appendPattern("HHmmss")
.appendFraction(ChronoField.NANO_OF_SECOND, 3, 4, true)
.toFormatter(Locale.ROOT);
static ZoneId zone = ZoneId.of("Europe/Paris");
public static ZonedDateTime utcToLocalTimeFromLock(String timestamp) {
return LocalDate.now(ZoneOffset.UTC)
.atTime(LocalTime.parse(timestamp, timeFormatter))
.atOffset(ZoneOffset.UTC)
.atZoneSameInstant(zone);
}
Let’s try:
System.out.println(utcToLocalTimeFromLock(timestamp));
Output when running just now:
2018-12-11T10:12:15+01:00[Europe/Paris]
The appendFraction method takes a minimum and maximum number of decimals after the point, so I specified 3 and 4, respectively. Depending on your needs you may specify a minimum down to 0 and a maximum up to 9 digits.
Of course replace your own time zone if it didn’t happen to Europe/Paris.
If you indispensably need an old-fashioned Date object for a legacy API that you don’t want to upgrade just now:
public static Date utcToLocalTimeFromLock(String timestamp) {
Instant inst= LocalDate.now(ZoneOffset.UTC)
.atTime(LocalTime.parse(timestamp, timeFormatter))
.atOffset(ZoneOffset.UTC)
.toInstant();
return Date.from(inst);
}
Tue Dec 11 10:12:15 CET 2018
If using the backport (ThreeTen Backport and/or ThreeTenABP, see below) for conversion from Instant to Date instead of Date.from(inst) use this:
return DateTimeUtils.toDate(inst);
Because a Date doesn’t have a time zone, no time zone conversion is necessary in this case. Only because I happen to be in Central European Time zone too, does the output agree with what you expect — it will be the time in the JVM’s time zone.
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
java.time
You are using terrible old date-time classes that were supplanted years ago by the industry-leading java.time classes.
Capture the current moment in UTC as an OffsetDateTime object.
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC ) ;
Parse the time-of-day as a LocalTime.
String input = "091215.000" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "HHmmss.SSS" ) ;
LocalTime lt = LocalTime.parse( input ) ;
Apply our time of day.
OffsetDateTime odt = now.with( lt ) ;
You may have a problem near the stroke of midnight. You might want to add some code to see if the captured current time is in a new day but your time-of-day is shortly before midnight yesterday. If so subtract a day from now. Use whatever boundary time-of-day values make sense in your situation.
if (
lt.isAfter( LocalTime.of( 23 , 55 ) )
&&
odt.toLocalTime().isBefore( LocalTime.of( 0 , 5 ) )
) {
now = now.minusDays( 1 ) ;
}
Adjust from UTC to your desired time zone.
ZoneId z = ZoneId( "Africa/Tunis" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
For Android <26, see the ThreeTenABP project.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Related
I have to count the number of times depending on year, month, day, hour, minute.(second is unified to zero, I don't need second)
I chose HashMap as the data structure.
HashMap<Calendar,Integer> arr_time;
If there are same time(year,month,day,hour,minute) already, I want to increase the Integer, or add a new time(year,month,day,hour,minute).
Calendar calendar = Calendar.getInstance();
calendar.set(mYear,mMonth,mDay,mHour,mMinute,0);
if(arr_time.containsKey(calendar)){
// increase Integer value
// ++1;
}else{
// add new time
// arr_time.put(calendar,1);
}
I thought it would recognize the same calendar if year, month, day, hour, and minute were the same.
But it was not.
What is the problem?
I didn't use "Date".
It's because, Android Devloper said like this.
Date(int year, int month, int date, int hrs, int min, int sec)
This constructor was deprecated in API level 1. As of JDK version 1.1, replaced by Calendar.set(year + 1900, month, date, hrs, min, sec) or GregorianCalendar(year + 1900, month, date, hrs, min, sec).
Never use Calendar
The terrible Calendar class was supplanted by the java.time classes years ago, specifically ZonedDateTime.
Time zone
You are ignoring the crucial issue of time zone. A date and time-of-day have no real meaning until you provide the context of time zone (or offset-from-UTC). For example, noon is Europe/Paris is much later than noon in Asia/Tokyo and much earlier than noon in America/Montreal.
ZonedDateTime
Represent a date and time-of-day with time zone with the ZonedDateTime class.
ZoneID
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
truncatedTo
If you want to set the second and fractional second both to zero, truncate to the minute.
ZonedDateTime zdt = ZonedDateTime.now( z ).truncatedTo( ChronoUnit.MINUTES ) ; // Set the whole second and the fractional second both to zero.
LocalDateTime
If, for your counting purposes, you want to consider only the date with time-of-day while ignoring the time zone, extract a LocalDateTime. A LocalDateTime is simply a date with time-of-day, and lacks any concept of time zone or offset-from-UTC.
LocalDateTime ldt = zdt.toLocalDateTime() ;
Map ➙ SortedMap ➙ TreeMap
With a LocalDateTime in hand, you can do your counting. Make a Map where the key is a LocalDateTime, and the value is an Integer.
I imagine you will care about the sorted order of the date-time keys, so use a SortedMap. A TreeMap is one such implementation.
SortedMap< LocalDateTime , Integer > map = new TreeMap() ;
For each LocalDateTime, retrieve an Integer object from the Map. Increment the number count, and replace the old Integer object with a new one.
Using a Map has been covered many hundreds, if not thousands, of times already on Stack Overflow. So search if you need more discussion and examples of that.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
java.time
Map<LocalDateTime, Integer> arr_time = new HashMap<>();
ZoneId zone = ZoneId.of("Antarctica/Vostok");
for (int i = 0; i < 10; i++) {
LocalDateTime now = LocalDateTime.now(zone).truncatedTo(ChronoUnit.MINUTES);
arr_time.compute(now, (ldt, oldCount) -> oldCount == null ? Integer.valueOf(1) : oldCount + 1);
TimeUnit.MILLISECONDS.sleep(103);
}
System.out.println(arr_time);
When I ran the code just now, I got:
{2019-02-20T13:42=10}
I recorded 10 times, sleeping in between to make sure they were not exactly the same. But because I truncated each to whole minutes, they all ended up being 2019-02-20T13:42 and were counted together.
To create a LocalDateTime from int variables:
int mYear = 2019;
int mMonth = Calendar.JANUARY;
int mDay = 31;
int mHour = 23;
int mMinute = 45;
LocalDateTime ldt = LocalDateTime.of(mYear, mMonth + 1, mDay, mHour, mMinute);
System.out.println(ldt);
2019-01-31T23:45
Since you used mMonth with Calendar, I assumed it was 0-based. LocalDateTime numbers months from 1, just like humans do, so I needed to add 1.
What went wrong in your code?
calendar.set(mYear,mMonth,mDay,mHour,mMinute,0) sets year, month, day, hour, minute and second but is not setting the milliseconds. Since each Calendar object is created with the current time, the milliseconds will most often be different, so the even though you set the same values, the Calendar objects are still not equal.
That behaviour of the 6-arg set method surprises many and is just a minor point among the many points where the class is poorly designed. You shouldn’t use it. We’ve got java.time since 2014, so there’s really no reason to.
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
How to find current date in java. I found a lot but every time i got same command
Date d = new Date(); or something similar
Every such command returns a date of 1970 year.
I fail to understand, Whats the benefit of this getting a date of 1970 ?
Is there any way where i can get current time and add a second into it.
My real purpose is to convert a long value into Date and add a second in it.
5:40:12 should give me 5:40:13 after adding a second.
Any help would be appreciated as i am fed up getting 1970 date.
My real purpose is to convert a long value into Date and add a second in it. 5:40:12 should give me 5:40:13 after adding a second
The troublesome java.util.Date class is now legacy, supplanted by the java.time classes.
Instant.ofEpochMilli( yourLongIntegerGoesHere ) // A moment on the timeline in UTC represented a count of nanoseconds since the epoch of `1970-01-01T00:00:00Z`.
.atZone( ZoneId.of( "Pacific/Auckland" ) // Time zone for the region whose wall-clock time you want to see.
.plusSeconds( 1 )
.toLocalTime() // Extract just the time-of-day without date and without time zone.
.toString() // Generate a string representing the time-of-day value in standard ISO 8601 format.
05:40:13
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Java.Util.Date class is deprecated, I would recommend using
Java.Util.Calendar instead.
If you're looking to add a second to Current date, try something like this:
Calendar currentTime = Calendar.getInstance(); // gets a calendar using the default time zone and locale.
calendar.add(currentTime.SECOND, 1);
System.out.println(currentTime.getTime());
BUT, the reason why you are receiving a 1970 date when using the Date class is because that class works with milliseconds, so you must multiply the long value by 1000 in order for it to convert to a date, here's an example.
Date currentDate = new Date( YourLongValue * 1000);
I try to format a time interval using SimpleDateFormat.
import java.text.*;
import java.util.*;
public class DateFormatTest {
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
long interval = 1000;
System.out.println("Interval in millis: " + interval);
System.out.println("Expected result: 00:00:01");
System.out.println("Result using Date and SimpleDateFormat: " +
sdf.format(new Date(interval)));
}
}
I get the following result:
Interval in millis: 1000
Expected result: 00:00:01
Result using Date and SimpleDateFormat: 01:00:01
I am in GMT+1 time zone. But it should not be reflected in the result.
Of course it can be solved with System.out.printf, but what I am searching is the reason.
I am in GMT+1 time zone. But should not be reflected in the result.
What makes you think so? new Date(0) is at 00:00AM GMT on Jan 1st 1970. So it is at 01:00AM if your default timezone is GMT + 1.
I am in GMT+1 time zone. But it should not be reflected in the result.
Then you should set the time zone in the SimpleDateFormat. SimpleDateFormat is doing exactly the right thing - it's formatting the instant in time (just after midnight UTC 1970) in the time zone it's working in.
To change the time zone, just use:
sdf.setTimeZone(TimeZone.getTimeZone("etc/UTC"));
It's not clear whether you should really be using SimpleDateFormat at all, though. You're not trying to format a date/time - you're trying to format an interval, given your variable name.
I suggest you use Joda Time which has a much richer type system, and will allow you to express what you really want.
Also, if you really want to use SimpleDateFormat, you probably want to use HH instead of hh in your format string. (hh is a 12-hour value, 1-12. You want 00:00:01, not 12:00:01.) hh is rarely appropriate when you don't also have an am/pm designator in your pattern.
Wrong data type
You are using the wrong class. You are trying to represent a duration of milliseconds and a time-of-day. Neither fits the Date class. That class represents a moment (a date, with time-of-day, in context of UTC).
Also, java.util.Date is a terrible class, designed by people who did not understand date-time handling. Now obsolete.
java.time
The modern solution uses java.time classes.
LocalTime
Specifically, LocalTime for a time-of-day using a generic 24-hour day, without a date, and without the context of a time zone or offset-from-UTC.
The start of a day for generic days is 00:00:00. We have a constant for that: LocalTime.MIN. But know that in various time zones, on various dates, the day may start at another time such as 01:00:00.
LocalTime lt = LocalTime.of( 15 , 30 ) ; // 3:30 PM.
Duration
To represent a span-of-time unattached to the timeline, on a scale of hours-minutes-seconds, use Duration class.
Duration d = Duration.ofMilliseconds( 1_000 ) ;
We can do math with date-time objects.
LocalTime lt = LocalTime.MIN.plus( d ) ;
You should know that java.time classes use a resolution of nanoseconds, much finer than the milliseconds used by the legacy date-time classes.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I am trying to write some code to correctly set an expiration date given a certain date.
For instance this is what i have.
Date lastSignupDate = m.getLastSignupDate();
long expirationDate = 0;
long milliseconds_in_half_year = 15778463000L;
expirationDate = lastSignupDate.getTime() + milliseconds_in_half_year;
Date newDate = new Date(expirationDate);
However, say if i the sign up date is on 5/7/2011 the expiration date output i get is on 11/6/2011 which is not exactly half of a year from the given date. Is there an easier way to do this?
I would use the Calendar class - the add method will do this kind of thing perfectly.
http://download.oracle.com/javase/6/docs/api/java/util/Calendar.html
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.MONTH, 6);
java.util.Date expirationDate = cal.getTime();
System.err.println(expirationDate);
Here's a simple suggestion using joda-time:
DateTime dt = new DateTime(lastSignupDate);
dt = dt.plusDays(DateTimeConstants.MILLIS_PER_DAY * 365 / 2);
// you can also use dt.plusDays(364 / 2);
You can also use a Calendar:
Calendar c = Calendar.getInstance();
c.setTime(lastSignupDate);
c.add(Calendar.MILLISECOND, MILLIS_PER_DAY * 365 / 2);
// or c.add(Calendar.DAY_OF_YEAR, 364 / 2);
tl;dr
java.time.LocalDate.of( 2011 , Month.MAY , 7 )
.plusMonths( 6 )
.toString()
2011-11-07
java.time
You are using date-time values, so you must account for issues such as time zones, anomalies, and leap year. But you only want a date without a time-of-day and without a time zone, so much easier if you use a date-only class rather than a date-with-time class.
The modern approach uses java.time rather than the troublesome legacy date-time classes.
if i the sign up date is on 5/7/2011 the expiration date output i get is on 11/6/2011 which is not exactly half of a year from the given date
The LocalDate class represents a date-only value without time-of-day and without time zone.
LocalDate ld = LocalDate.of( 2011 , Month.MAY , 7 ) ;
You can do math with the java.time classes. Look for plus… and minus… methods.
LocalDate sixMonthsLater = ld.plusMonths( 6 ) ;
Or pass the amount of time.
Period p = Period.ofMonths( 6 ) ;
LocalDate sixMonthsLater = ld.plus( p ) ;
See this code run live at IdeOne.com.
2011-05-07
2011-11-07
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Do you really need an expiration-date, which is accurate to the millisecond?
I would implement it as 6 Months from x.
Jan. 1 => Jul 1
Sep. 28=> Feb 28
Sep. 29=> Feb 28
Sep. 30=> Feb 28
Oct. 1=> Mar 1
Maybe you like to be generous, and say 'Mar 1' for 'Sep 29 and 30' too.
Here's an example of using Date with TimeUnit that's a little more readable:
long year = TimeUnit.MILLISECONDS.convert(365, TimeUnit.DAYS);
Date expiry = new Date(System.currentTimeMillis() + year);
System.out.println(expiry);
Shame it doesn't have year and day, look at GregorianCalendar or Jodatime for a better API.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(new Date().getTime());
// 10 minutes expiration time
calendar.add(calendar.MINUTE, 10);
// prints 10 minutes ahead time
System.out.println(new Date(calendar.getTime().getTime()));
I'm using a Gregorian Calendar to set a specific date and time to an application using the set function of the Gregorian Calendar. When i use the getTime() method, it gives me the right output however when i try to access the Hour_Of_Day and Minute it gives a wrong number.
Calendar time = new GregorianCalendar();
time.set(2010, Calendar.JANUARY, 1, 7, 20,0);
hour = time.HOUR_OF_DAY;
minute = time.MINUTE;
The hour gives an output of 11 and the minute gives an a value of 12.
Any suggestions on how to fix this?
Thanks
Your code is just assigning hour/minute to constants. You need to call Calendar.get(int):
hour = time.get(Calendar.HOUR_OF_DAY);
minute = time.get(Calendar.MINUTE);
tl;dr
myGregCal
.toZonedDateTime() // Convert from legacy class GregorianCalendar to modern ZonedDateTime.
.getHour() // Get hour-of-day, 0-23.
java.time
Much easier with the modern java.time classes that replace those troublesome old legacy date-time classes.
The ZonedDateTime class represents a moment on the timeline in a specific time zone with a resolution of nanoseconds.
Convert from your GregorianCalendar using new methods added to the old classes.
ZonedDateTime zdt = myGregCal.toZonedDateTime() ;
Or start fresh without the GregorianCalendar class.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.of( 2010 , Month.JANUARY , 1 , 7 , 20 , 0 , 0 , z );
If you want to work with just the time-of-day portion, extract a LocalTime.
LocalTime localTime = zdt.toLocalTime() ;
If you really want the integer numbers of hours and minutes, you can interrogate for those.
int hour = zdt.getHour();
int minute = zdt.getMinute();
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.