This code is working, but I want to use Joda-Time
public static Date dateFromUTC(Date date){
return new Date(date.getTime() + Calendar.getInstance().getTimeZone().getOffset(date.getTime()));
}
I tried this, but it's not working - what's the problem with this?
public static Date dateFromUTC(Date date){
return new DateTime(date).withZone(DateTimeZone.getDefault()).toDate();
}
tl;dr
Use java.time classes instead.
Instant.now() // Capture current moment in UTC. Always in UTC, by definition.
…and…
ZonedDateTime.now() // Capture current moment as seen through the wall-clock time of the people in the region of the time zone used by default in this JVM.
Details
As others said, you misunderstood the concepts involved in these classes. A java.util.Date represents a moment in UTC, always in UTC†, never in some other time zone. So the code seen in the Question is non-sensical. You are working too hard!
java.time
The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. Many of the concepts are similar between Joda-Time and java.time as both projects are led by the same man, Stephen Colebourne.
When you are ready to migrate, use Instant in place of java.util.Date.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
instant.toString(): 2018-01-23T12:34:56.123456789Z
Instead of java.util.Calendar, use ZonedDateTime to represent a moment seen through the wall-clock time of a particular region (a time zone).
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-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 = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
As a shortcut, you can skip the Instant if you want only the zoned time.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment as seen by people in a certain time zone.
You can get to UTC from there by extracting an Instant object.
Instant instant = zdt.toInstant() ; // Same moment, same point on the timeline, but viewed with the wall-clock time of UTC.
† Actually, there is a time zone assigned deep within a java.util.Date but is irrelevant to our discussion here. Confusing? Yes. One of many reasons to avoid the awful mess that is the old Date/Calendar and related 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.
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, 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 (<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.
Try this:
new DateTime(date, DateTimeZone.UTC)
.toLocalDateTime() // value without timezone
.toDateTime() // convert to default timezone
.toDate();
Your code actually does nothing to the date, because new DateTime(date) creates a DateTime object with default timezone. And then you just convert it back to java.util.Date.
First of all, read the article linked in the comments: https://codeblog.jonskeet.uk/2017/04/23/all-about-java-util-date/
A java.util.Date doesn't have a timezone. It actually represents a point in time: the number of milliseconds since unix epoch (Jan 1st 1970, at midnight, in UTC).
When you print the Date, though, it uses the JVM default timezone to convert the Date to date/time values, but the Date itself doesn't have a timezone.
That's why converting a Date object to another timezone doesn't make sense.
If you want to know the date (day, month, year) and time (hour, minute, second, millisecond) that corresponds to the Date in a specific timezone, then you can use Joda-Time:
// java.util.Date
Date date = new Date();
// the Date converted to UTC
DateTime utc = new DateTime(date, DateTimeZone.UTC);
// the Date converted to JVM default timezone
DateTime convertedToDefaultTz= new DateTime(date, DateTimeZone.getDefault());
The conversion can also be made using another DateTime:
DateTime convertedToDefaultTz = utc.withZone(DateTimeZone.getDefault());
Joda's DateTime has a timezone attached to it, so now it makes sense to convert to another one. But the Date objects returned by it will always be the same, because all of them represent the same instant (the same point in the timeline):
Date d1 = utc.toDate();
Date d2 = convertedToDefaultTz.toDate();
System.out.println(d1.equals(d2)); // true
All because - again - a Date doesn't have a timezone.
Related
I need to convert a unix timestamp to a date object.
I tried this:
java.util.Date time = new java.util.Date(timeStamp);
Timestamp value is: 1280512800
The Date should be "2010/07/30 - 22:30:00" (as I get it by PHP) but instead I get Thu Jan 15 23:11:56 IRST 1970.
How should it be done?
For 1280512800, multiply by 1000, since java is expecting milliseconds:
java.util.Date time=new java.util.Date((long)timeStamp*1000);
If you already had milliseconds, then just new java.util.Date((long)timeStamp);
From the documentation:
Allocates a Date object and
initializes it to represent the
specified number of milliseconds since
the standard base time known as "the
epoch", namely January 1, 1970,
00:00:00 GMT.
java.time
Java 8 introduced a new API for working with dates and times: the java.time package.
With java.time you can parse your count of whole seconds since the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00Z. The result is an Instant.
Instant instant = Instant.ofEpochSecond( timeStamp );
If you need a java.util.Date to interoperate with old code not yet updated for java.time, convert. Call new conversion methods added to the old classes.
Date date = Date.from( instant );
This is the right way:
Date date = new Date ();
date.setTime((long)unix_time*1000);
tl;dr
Instant.ofEpochSecond( 1_280_512_800L )
2010-07-30T18:00:00Z
java.time
The new java.time framework built into Java 8 and later is the successor to Joda-Time.
These new classes include a handy factory method to convert a count of whole seconds from epoch. You get an Instant, a moment on the timeline in UTC with up to nanoseconds resolution.
Instant instant = Instant.ofEpochSecond( 1_280_512_800L );
instant.toString(): 2010-07-30T18:00:00Z
See that code run live at IdeOne.com.
Asia/Kabul or Asia/Tehran time zones ?
You reported getting a time-of-day value of 22:30 instead of the 18:00 seen here. I suspect your PHP utility is implicitly applying a default time zone to adjust from UTC. My value here is UTC, signified by the Z (short for Zulu, means UTC). Any chance your machine OS or PHP is set to Asia/Kabul or Asia/Tehran time zones? I suppose so as you report IRST in your output which apparently means Iran time. Currently in 2017 those are the only zones operating with a summer time that is four and a half hours ahead of UTC.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST or IRST as they are not true time zones, not standardized, and not even unique(!).
If you want to see your moment through the lens of a particular region's time zone, apply a ZoneId to get a ZonedDateTime. Still the same simultaneous moment, but seen as a different wall-clock time.
ZoneId z = ZoneId.of( "Asia/Tehran" ) ;
ZonedDateTime zdt = instant.atZone( z ); // Same moment, same point on timeline, but seen as different wall-clock time.
2010-07-30T22:30+04:30[Asia/Tehran]
Converting from java.time to legacy classes
You should stick with the new java.time classes. But you can convert to old if required.
java.util.Date date = java.util.Date.from( instant );
Joda-Time
UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes.
FYI, the constructor for a Joda-Time DateTime is similar: Multiply by a thousand to produce a long (not an int!).
DateTime dateTime = new DateTime( ( 1_280_512_800L * 1000_L ), DateTimeZone.forID( "Europe/Paris" ) );
Best to avoid the notoriously troublesome java.util.Date and .Calendar classes. But if you must use a Date, you can convert from Joda-Time.
java.util.Date date = dateTime.toDate();
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, 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 (<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.
Looks like Calendar is the new way to go:
Calendar mydate = Calendar.getInstance();
mydate.setTimeInMillis(timestamp*1000);
out.println(mydate.get(Calendar.DAY_OF_MONTH)+"."+mydate.get(Calendar.MONTH)+"."+mydate.get(Calendar.YEAR));
The last line is just an example how to use it, this one would print eg "14.06.2012".
If you have used System.currentTimeMillis() to save the Timestamp you don't need the "*1000" part.
If you have the timestamp in a string you need to parse it first as a long: Long.parseLong(timestamp).
https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html
Date's constructor expects the timeStamp value to be in milliseconds.
Multiply your timestamp's value with 1000, then pass it to the constructor.
If you are converting a timestamp value on a different machine, you should also check the timezone of that machine. For example;
The above decriptions will result different Date values, if you run with EST or UTC timezones.
To set the timezone; aka to UTC,
you can simply rewrite;
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
java.util.Date time= new java.util.Date((Long.parseLong(timestamp)*1000));
For kotlin
fun unixToDate(timeStamp: Long) : String? {
val time = java.util.Date(timeStamp as Long * 1000)
val sdf = SimpleDateFormat("yyyy-MM-dd")
return sdf.format(time)
}
Sometimes you need to work with adjustments.
Don't use cast to long! Use nanoadjustment.
For example, using Oanda Java API for trading you can get datetime as UNIX format.
For example: 1592523410.590566943
System.out.println("instant with nano = " + Instant.ofEpochSecond(1592523410, 590566943));
System.out.println("instant = " + Instant.ofEpochSecond(1592523410));
you get:
instant with nano = 2020-06-18T23:36:50.590566943Z
instant = 2020-06-18T23:36:50Z
Also, use:
Date date = Date.from( Instant.ofEpochSecond(1592523410, 590566943) );
LocalDateTime is another choice, like:
LocalDateTime.ofInstant(Instant.ofEpochSecond(unixtime), ZoneId.systemDefault())
Date d = new Date(i * 1000 + TimeZone.getDefault().getRawOffset());
I need to convert a unix timestamp to a date object.
I tried this:
java.util.Date time = new java.util.Date(timeStamp);
Timestamp value is: 1280512800
The Date should be "2010/07/30 - 22:30:00" (as I get it by PHP) but instead I get Thu Jan 15 23:11:56 IRST 1970.
How should it be done?
For 1280512800, multiply by 1000, since java is expecting milliseconds:
java.util.Date time=new java.util.Date((long)timeStamp*1000);
If you already had milliseconds, then just new java.util.Date((long)timeStamp);
From the documentation:
Allocates a Date object and
initializes it to represent the
specified number of milliseconds since
the standard base time known as "the
epoch", namely January 1, 1970,
00:00:00 GMT.
java.time
Java 8 introduced a new API for working with dates and times: the java.time package.
With java.time you can parse your count of whole seconds since the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00Z. The result is an Instant.
Instant instant = Instant.ofEpochSecond( timeStamp );
If you need a java.util.Date to interoperate with old code not yet updated for java.time, convert. Call new conversion methods added to the old classes.
Date date = Date.from( instant );
This is the right way:
Date date = new Date ();
date.setTime((long)unix_time*1000);
tl;dr
Instant.ofEpochSecond( 1_280_512_800L )
2010-07-30T18:00:00Z
java.time
The new java.time framework built into Java 8 and later is the successor to Joda-Time.
These new classes include a handy factory method to convert a count of whole seconds from epoch. You get an Instant, a moment on the timeline in UTC with up to nanoseconds resolution.
Instant instant = Instant.ofEpochSecond( 1_280_512_800L );
instant.toString(): 2010-07-30T18:00:00Z
See that code run live at IdeOne.com.
Asia/Kabul or Asia/Tehran time zones ?
You reported getting a time-of-day value of 22:30 instead of the 18:00 seen here. I suspect your PHP utility is implicitly applying a default time zone to adjust from UTC. My value here is UTC, signified by the Z (short for Zulu, means UTC). Any chance your machine OS or PHP is set to Asia/Kabul or Asia/Tehran time zones? I suppose so as you report IRST in your output which apparently means Iran time. Currently in 2017 those are the only zones operating with a summer time that is four and a half hours ahead of UTC.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST or IRST as they are not true time zones, not standardized, and not even unique(!).
If you want to see your moment through the lens of a particular region's time zone, apply a ZoneId to get a ZonedDateTime. Still the same simultaneous moment, but seen as a different wall-clock time.
ZoneId z = ZoneId.of( "Asia/Tehran" ) ;
ZonedDateTime zdt = instant.atZone( z ); // Same moment, same point on timeline, but seen as different wall-clock time.
2010-07-30T22:30+04:30[Asia/Tehran]
Converting from java.time to legacy classes
You should stick with the new java.time classes. But you can convert to old if required.
java.util.Date date = java.util.Date.from( instant );
Joda-Time
UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes.
FYI, the constructor for a Joda-Time DateTime is similar: Multiply by a thousand to produce a long (not an int!).
DateTime dateTime = new DateTime( ( 1_280_512_800L * 1000_L ), DateTimeZone.forID( "Europe/Paris" ) );
Best to avoid the notoriously troublesome java.util.Date and .Calendar classes. But if you must use a Date, you can convert from Joda-Time.
java.util.Date date = dateTime.toDate();
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, 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 (<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.
Looks like Calendar is the new way to go:
Calendar mydate = Calendar.getInstance();
mydate.setTimeInMillis(timestamp*1000);
out.println(mydate.get(Calendar.DAY_OF_MONTH)+"."+mydate.get(Calendar.MONTH)+"."+mydate.get(Calendar.YEAR));
The last line is just an example how to use it, this one would print eg "14.06.2012".
If you have used System.currentTimeMillis() to save the Timestamp you don't need the "*1000" part.
If you have the timestamp in a string you need to parse it first as a long: Long.parseLong(timestamp).
https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html
Date's constructor expects the timeStamp value to be in milliseconds.
Multiply your timestamp's value with 1000, then pass it to the constructor.
If you are converting a timestamp value on a different machine, you should also check the timezone of that machine. For example;
The above decriptions will result different Date values, if you run with EST or UTC timezones.
To set the timezone; aka to UTC,
you can simply rewrite;
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
java.util.Date time= new java.util.Date((Long.parseLong(timestamp)*1000));
For kotlin
fun unixToDate(timeStamp: Long) : String? {
val time = java.util.Date(timeStamp as Long * 1000)
val sdf = SimpleDateFormat("yyyy-MM-dd")
return sdf.format(time)
}
Sometimes you need to work with adjustments.
Don't use cast to long! Use nanoadjustment.
For example, using Oanda Java API for trading you can get datetime as UNIX format.
For example: 1592523410.590566943
System.out.println("instant with nano = " + Instant.ofEpochSecond(1592523410, 590566943));
System.out.println("instant = " + Instant.ofEpochSecond(1592523410));
you get:
instant with nano = 2020-06-18T23:36:50.590566943Z
instant = 2020-06-18T23:36:50Z
Also, use:
Date date = Date.from( Instant.ofEpochSecond(1592523410, 590566943) );
LocalDateTime is another choice, like:
LocalDateTime.ofInstant(Instant.ofEpochSecond(unixtime), ZoneId.systemDefault())
Date d = new Date(i * 1000 + TimeZone.getDefault().getRawOffset());
Why does java.util.Date object show date & time with respect to a timezone when in actuality, java.util.Date represents an instant on the time-line, not a "date"?
The actual data stored within the object is a long count of milliseconds since 1970-01-01T00:00Z (midnight at the start of 1970 GMT/UTC).
Also in docs, A java.util.Date instance has no concept of time-zone.
If so is the case, why does this snippet print date specifying timezone.
public static void main(String[] args) {
Date date = new Date();
System.out.println(date);
}
Output : Wed Mar 22 14:58:56 IST 2017
Why is it showing specific timezone in the output? I understand the SOP implements toString() internally. Does toString() effect the timezone?
Just follow the javadoc, as it says:
public String toString()
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
zzz is the time zone (and may reflect daylight saving time).
And when you dive into the source code, that this toString() implementation will at some point use TimeZone.getDefault()
( or to be precise: getDefaultRef()). In other words: the default implementation pulls in the "default" timezone of your JVM.
tl;dr
Current moment in UTC.
Instant.now() // Capture current moment in UTC.
.toString() // Generate String in standard ISO 8601 format.
2018-01-23T01:23:45.677340Z
Current moment in India time zone.
ZonedDateTime.now(
ZoneId.of( "Asia/Kolkata" )
).toString() // Generate string in format wisely extended from ISO 8601 standard, adding the time zone name in square brackets.
2018-01-23T06:53:45.677340+05:30[Asia/Kolkata]
Avoid legacy date-time classes
Why does java.util.Date object show date & time with respect to a timezone when in actuality, java.util.Date represents an instant on the time-line, not a "date"?
Because the java.util.Date and related classes (Calendar, SimpleDateFormat, and such) are poorly-designed. While a valiant effort at tackling the tricky subject of date-time handling, they fall short of the goal. They are riddled with poor design choices. You should avoid them, as they are now supplanted by the java.time classes, an enormous improvement.
Specifically to answer your question: The toString method of Date dynamically applies the JVM’s current default time zone while generating a String. So while the Date object itself represents a moment in UTC, the toString creates the false impression that it carries the displayed time zone.
Even worse, there is a time zone buried inside the Date object. That zone is used internally, yet is irrelevant to our discussion here. Confusing? Yes, yet another reason to avoid this class.
A java.util.Date instance has no concept of time-zone.
Not true. A Date represents a specific moment, a point on the timeline, with a resolution of milliseconds, in UTC. As you mention, it is defined as a count of milliseconds since the first moment of 1970 in UTC.
java.time
The java.time classes separate clearly the concepts of UTC, zoned, and unzoned values.
The java.time.Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction). This class replaces java.util.Date.
Instant instant = Instant.now() ; // Capture current moment in UTC.
Apply a time zone (ZoneId object) to an Instant and you get a ZonedDateTime object. That class replaces the java.util.Calendar class.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same simultaneous moment as `instant`, but different wall-clock time.
If a value has only an offset-from-UTC but not a full time zone, use the OffsetDateTime class.
For a date only, without time-of-day and without time zone, use the LocalDate class. This class replaces the java.sql.Date class. Ditto for LocalTime replacing java.sql.Time.
LocalDate xmasDate2018 = LocalDate.of( 2018 , Month.DECEMBER , 25 ) ;
If the zone or offset are unknown or indeterminate, such as "Christmas starts at stroke of midnight on December 25, 2018", use the LocalDateTime class. This class does not represent an actual moment, a specific point on the timeline. This class lacks any concept of time zone or offset. So it can only represent potential moments along a range of about 26-27 hours.
LocalDateTime xmasEverywhere2018 = LocalDateTime.of( xmasDate2018 , LocalTime.MIN ) ;
Or…
LocalDateTime xmasEverywhere2018 = LocalDateTime.of( 2018 , Month.DECEMBER , 25 , 0 , 0 , 0 , 0 ) ;
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.
With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or java.sql.* classes.
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.
It does have a concept of time zone, but it is always UTC. When it prints the date therefore there is no problem converting it to the time zone of your computer.
I need to convert a unix timestamp to a date object.
I tried this:
java.util.Date time = new java.util.Date(timeStamp);
Timestamp value is: 1280512800
The Date should be "2010/07/30 - 22:30:00" (as I get it by PHP) but instead I get Thu Jan 15 23:11:56 IRST 1970.
How should it be done?
For 1280512800, multiply by 1000, since java is expecting milliseconds:
java.util.Date time=new java.util.Date((long)timeStamp*1000);
If you already had milliseconds, then just new java.util.Date((long)timeStamp);
From the documentation:
Allocates a Date object and
initializes it to represent the
specified number of milliseconds since
the standard base time known as "the
epoch", namely January 1, 1970,
00:00:00 GMT.
java.time
Java 8 introduced a new API for working with dates and times: the java.time package.
With java.time you can parse your count of whole seconds since the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00Z. The result is an Instant.
Instant instant = Instant.ofEpochSecond( timeStamp );
If you need a java.util.Date to interoperate with old code not yet updated for java.time, convert. Call new conversion methods added to the old classes.
Date date = Date.from( instant );
This is the right way:
Date date = new Date ();
date.setTime((long)unix_time*1000);
tl;dr
Instant.ofEpochSecond( 1_280_512_800L )
2010-07-30T18:00:00Z
java.time
The new java.time framework built into Java 8 and later is the successor to Joda-Time.
These new classes include a handy factory method to convert a count of whole seconds from epoch. You get an Instant, a moment on the timeline in UTC with up to nanoseconds resolution.
Instant instant = Instant.ofEpochSecond( 1_280_512_800L );
instant.toString(): 2010-07-30T18:00:00Z
See that code run live at IdeOne.com.
Asia/Kabul or Asia/Tehran time zones ?
You reported getting a time-of-day value of 22:30 instead of the 18:00 seen here. I suspect your PHP utility is implicitly applying a default time zone to adjust from UTC. My value here is UTC, signified by the Z (short for Zulu, means UTC). Any chance your machine OS or PHP is set to Asia/Kabul or Asia/Tehran time zones? I suppose so as you report IRST in your output which apparently means Iran time. Currently in 2017 those are the only zones operating with a summer time that is four and a half hours ahead of UTC.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST or IRST as they are not true time zones, not standardized, and not even unique(!).
If you want to see your moment through the lens of a particular region's time zone, apply a ZoneId to get a ZonedDateTime. Still the same simultaneous moment, but seen as a different wall-clock time.
ZoneId z = ZoneId.of( "Asia/Tehran" ) ;
ZonedDateTime zdt = instant.atZone( z ); // Same moment, same point on timeline, but seen as different wall-clock time.
2010-07-30T22:30+04:30[Asia/Tehran]
Converting from java.time to legacy classes
You should stick with the new java.time classes. But you can convert to old if required.
java.util.Date date = java.util.Date.from( instant );
Joda-Time
UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes.
FYI, the constructor for a Joda-Time DateTime is similar: Multiply by a thousand to produce a long (not an int!).
DateTime dateTime = new DateTime( ( 1_280_512_800L * 1000_L ), DateTimeZone.forID( "Europe/Paris" ) );
Best to avoid the notoriously troublesome java.util.Date and .Calendar classes. But if you must use a Date, you can convert from Joda-Time.
java.util.Date date = dateTime.toDate();
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, 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 (<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.
Looks like Calendar is the new way to go:
Calendar mydate = Calendar.getInstance();
mydate.setTimeInMillis(timestamp*1000);
out.println(mydate.get(Calendar.DAY_OF_MONTH)+"."+mydate.get(Calendar.MONTH)+"."+mydate.get(Calendar.YEAR));
The last line is just an example how to use it, this one would print eg "14.06.2012".
If you have used System.currentTimeMillis() to save the Timestamp you don't need the "*1000" part.
If you have the timestamp in a string you need to parse it first as a long: Long.parseLong(timestamp).
https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html
Date's constructor expects the timeStamp value to be in milliseconds.
Multiply your timestamp's value with 1000, then pass it to the constructor.
If you are converting a timestamp value on a different machine, you should also check the timezone of that machine. For example;
The above decriptions will result different Date values, if you run with EST or UTC timezones.
To set the timezone; aka to UTC,
you can simply rewrite;
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
java.util.Date time= new java.util.Date((Long.parseLong(timestamp)*1000));
For kotlin
fun unixToDate(timeStamp: Long) : String? {
val time = java.util.Date(timeStamp as Long * 1000)
val sdf = SimpleDateFormat("yyyy-MM-dd")
return sdf.format(time)
}
Sometimes you need to work with adjustments.
Don't use cast to long! Use nanoadjustment.
For example, using Oanda Java API for trading you can get datetime as UNIX format.
For example: 1592523410.590566943
System.out.println("instant with nano = " + Instant.ofEpochSecond(1592523410, 590566943));
System.out.println("instant = " + Instant.ofEpochSecond(1592523410));
you get:
instant with nano = 2020-06-18T23:36:50.590566943Z
instant = 2020-06-18T23:36:50Z
Also, use:
Date date = Date.from( Instant.ofEpochSecond(1592523410, 590566943) );
LocalDateTime is another choice, like:
LocalDateTime.ofInstant(Instant.ofEpochSecond(unixtime), ZoneId.systemDefault())
Date d = new Date(i * 1000 + TimeZone.getDefault().getRawOffset());
I have no idea why Java makes it near impossible to do such a simple thing. I have tried many solutions I find online, but there doesn't seem to be a simple clean and working solution.
Here is my latest attempt at a solution
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));
System.out.println( sdf.format(calendar.getTime()) );
My excepted output: 27/02/2014 17:06:00
My real output: 03/03/2014 20:35:44
How does this even make any sense.
set timezone in SimpleDateFormat instance instead
sdf.setTimezone("America/Los_Angeles");
tl;dr
ZonedDateTime.now()
Details
The real problem is using the notoriously troublesome java.util.Date and .Calendar classes. Use the modern java.time classes instead.
java.time
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-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( "America/Los_Angeles" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment, with wall-clock time used by people of a particular region.
See this code run live at IdeOne.com.
zdt.toString(): 2018-01-28T15:12:58.942-08:00[America/Los_Angeles]
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
To generate strings in other formats, search Stack Overflow for DateTimeFormatter.
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….
Joda-Time
UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. Leaving this section for history.
One important difference is that while a java.util.Date has no timezone, a DateTime (in Joda-Time) and a ZonedDateTime (in java.time) both truly know their own assigned time zone.
Example code in Joda-Time 2.3. If you choose to not specify a time zone, you get the JVM's default time zone. Use proper time zone names, never the 3 or 4 letter codes.
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime now = new DateTime( timeZone );
DateTime nowDefaultTimeZone = new DateTime();
String output is in ISO 8601 format (ex: 2014-02-27T23:03:14+3:00) by default. To create string representations in other formats, search StackOverflow for "joda format".
SimpleDateFormat sdf=new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
System.out.println(sdf.format(new Date()));
TimeZone timeZone=TimeZone.getDefault();
System.out.println(timeZone.getDisplayName());
TimeZone americaTimeZone=TimeZone.getTimeZone("America/Los_Angeles");
sdf.setTimeZone(americaTimeZone);
Calendar calendar=Calendar.getInstance(americaTimeZone);
System.out.println(sdf.format(calendar.getTime()));
SimpleDateFormat default format with default TimeZone;
After hours DuckDuckGoging I solved it in Android with (the call requires API level 24):
Calendar calendario = Calendar.getInstance(TimeZone.getTimeZone(Time.getCurrentTimezone()));