Given a year, month, day, hour, minute and second, what is the correct way to create a Java UTC (GMT) timestamp?
Options I've considered, but remain to be convinced by:
java.util.Date date = new java.util.Date(year - 1900, month, dayOfMonth, hour, minute, second);
long timestamp = date.getTime();
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
c.set(Calendar.YEAR, year);
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_MONTH, dayOfMonth);
c.set(Calendar.HOUR_OF_DAY, hour);
c.set(Calendar.MINUTE, minute);
c.set(Calendar.SECOND, second);
c.set(Calendar.MILLISECOND, 0);
long timestamp = c.getTimeInMillis();
One of my issues with this is that I'm finding it very hard to test without getting mixed up in more TimeZone issues.
Is there a definitive right way to do this with the standard APIs?
Update: would like to get an answer to this using standard JavaSE. I know Joda-Time is wonderful, but it's not an option in this case.
没有,没有(除非你可以使用乔达时间 ),正确的方法是使用日历和日历API 是丑陋的,任何人都无法在此刻做的。
Standard Java APIs for dates are pretty inconvenient. Consider using Joda-Time :
long timestamp = new LocalDateTime(year, month, day, hour, minute, second)
.getLocalMillis();
I think this would work pretty good
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
Date date = sdf.parse("2011-12-21 12:00:00+0000");
You would have to build the date string on your own but it's short and should work fine. And create the SimpleDateFormat to your liking, the important part is the Z that corresponds to "+0000".
Here is another alternative way on the same lines
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sdf.parse("2011-12-21 12:00:00");
It's with an explicit time zone and the Z is removed.
OffsetDateTime.of( 2018 , 1 , 23 , 12 , 34 , 56 , 0, ZoneOffset.UTC )
The modern approach uses the java.time classes.
Unlike the troublesome legacy date-time classes, the java.time classes use sane numbering:
2018
means the year 2018. (No crazy math with 1900.) The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
You a one-liner if you wish, if parsing a string.
Instant instant = Instant.parse( "2018-01-23T12:34:56Z" ) ;
While Instant
is a basic building-block class for java.time , the OffsetDateTime
class is more flexible. The offset-from-UTC of UTC itself is defined as a constant for your convenience.
OffsetDateTime odt = OffsetDateTime.of( 2018 , 1 , 23 , 12 , 34 , 56 , 0, ZoneOffset.UTC ) ;
Personally, I prefer using pieces.
In place of a mere integer for month, you may specify a Month
enum object.
LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 ) ; // Date-only, without time-of-day.
LocalTime lt = LocalTime.of( 12 , 34 , 56 ) ; // Time-of-day, without date.
ZoneOffset offset = ZoneOffset.UTC ;
OffsetDateTime odt = OffsetDateTime.of( ld , lt , offset ) ;
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 .
Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.
Where to obtain the java.time classes?
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 .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.