Why get different localDate with same timezone - java

java.sql.Date date = java.sql.Date.valueOf("1900-01-01");
org.joda.time.LocalDate localDate = new org.joda.time.LocalDate(date);
Based above code, I did some tests as below:
Question #1 why do I get different localDate object with same timezone?
If I change local timezone to UTC+8 Singapore Timezone, will get 1899-12-31
If I change local timezone to UTC+8 China Timezone, will get 1900-01-01
Question #2 why do I get same time with different timezone?
If I change local timezone to UTC-8 America/Los_Angeles Timezone, will get 1900-01-01
If I change local timezone to UTC+8 China Timezone, will get 1900-01-01
Could someone help clarify that?? it is little bit confused.

In 1900, Singpore's offset is UTC +6:55:25, so when you create date 1900-01-01 in Singapore time zone, it should be 1899-12-31T17:04:35Z[UTC] as below:
java.time.ZonedDateTime localDateTime = ZonedDateTime.of(1900, 01, 01, 0,
0, 0, 0, ZoneId.of("Singapore"));
System.out.println(localDateTime.withZoneSameInstant(ZoneId.of("UTC")));
// 1899-12-31T17:04:35Z[UTC]
However, when you use java.sql.Date, it use wrong offset UTC +08:00:
TimeZone.setDefault(TimeZone.getTimeZone("Singapore"));
java.sql.Date date = java.sql.Date.valueOf("1900-01-01");
java.time.Instant instant = Instant.ofEpochMilli(date.getTime());
System.out.println(instant); // 1899-12-31T16:00:00Z
and when you create org.joda.time.LocalDateTime with this wrong value, Joda use UTC +6:55:25 as offset, resulting in a date time 1899-12-31T16:00:00 + 6:55:25:
org.joda.time.LocalDateTime singaporeDateTime = new org.joda.time.LocalDateTime(date);
System.out.println(singaporeDateTime); // 1899-12-31T22:55:25.000
You can use the similar approach to check the result of Shanghai and Los Angelas, the point is, avoid using java.sql.Date and other deprecated date time related classes. Use java.time instead if you are working with java8 or higher.

tl;dr
java.time.LocalDate
.of(
1900 ,
Month.JANUARY ,
1
) ;
Avoid legacy date-time classes
You are using a terrible old class java.sql.Date that was badly designed with flawed hacks. Among its problems is that it pretends to represent a date-only value but actually holds a time-of-day. It even holds a time zone deep inside, though without getter or setter. Never use this class. Supplanted years ago by the java.time.LocalDate class.
The Joda-Time project too is supplanted by the java.time classes. The project is in maintenance mode, receiving updates and critical bug fixes but no new feature work. The project advises migration to the java.time classes. Migration is easy as they share similar concepts, both having been led by the same man, Stephen Colebourne.
java.time.LocalDate
Use java.time.LocalDate when you want a date-only value without time-of-day and without time zone. All your problems raised in your Question go away.
java.time.LocalDate ld = LocalDate.of( 1900 , Month.JANUARY , 1 ) ; // Simply a year-month-day date, no problems, no issues, no confusion.
ld.toString(): 1900-01-01
Also notice that java.time uses sane numbering where 2018 means the year 2018, and 1-12 means January-December. This is in distinct contrast to the troublesome legacy 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, 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

Date.from(ZonedDateTime to instant) returning previous day

My variable in java of type ZonedDateTime is say time="2017-01-03T00:00Z[UTZ]" . And when i try to get Date from like this - Date.from(time.toInstance()) it returns previous day i.e Mon Jan 02 19:00:00 EST 2017, I dont know why ? Could anyone shed some light on my it returns previous day ?
Avoid legacy date-time classes
Never use java.util.Date class. That terrible class, along with Calendar & SimpleDateFormat and others are now legacy. The new to/from conversion methods added to the old classes are intended only for use when you are interoperating with old code not yet updated to java.time. Avoid Date whenever possible.
Among the many flaws in Date is its unfortunate behavior of dynamically applying the JVM’s current default time zone while generating the text in its toString method. So it appears a Date has a time zone while actually a Date represents a moment in UTC. In other words, Date::toString lies. One of many reasons to avoid this class.
➥ In the winter of 2017, many of the time zones on the east coast of North America are five hours behind UTC. So midnight in UTC is simultaneously 7 PM (19:00) in New York, Montréal, etc. Same moment, different wall-clock time.
java.time
The Date class was supplanted by Instant years ago.
ZonedDateTime is say time="2017-01-03T00:00Z[UTZ]"
If you are trying to track moments in UTC, use either:
InstantInstant.now()
OffsetDateTime object set to UTC.OffsetDateTime.now( ZoneOffset.UTC )
Use the ZonedDateTime class when you have a moment in the context of a time zone. A time zone is a history of the past, present, and future changes to the offset-from-UTC used by the people of a particular region.
ZonedDateTime.now(
ZoneId.of( "Africa/Tunis" )
)
You can adjust between UTC and a zone. Same moment, different ways to view it, different wall-clock times.
ZonedDateTime zdt = instant.atZone( ZoneId.of( "Pacific/Auckland" ) ) ;
…and…
Instant instant = zdt.toInstant() ;
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.
ZonedDateTime.toInstant() adjusts a moment from a time zone to UTC. You end up with the same moment, different wall-clock time, and possibly a different date for the same simultaneous point on the timeline. What you are seeing is not a problem, not a discrepancy.
Classes like LocalDate and ZonedDateTime provide a human view on time.
However, often we need to work with time viewed from a machine perspective.
For this, we can use the Instant class which represents timestamps.
An Instant counts the time beginning from the first second of January 1, 1970 (1970-01-01 00:00:00) also called the EPOCH.
Instant values can be negative if they occurred before the epoch. They followISO 8601 the standard for representing date and time.
Also, use the Java Time API libraries introduced in Java 8 as there were many issues in the existing Date and Calendar APIs Please
refer: https://www.baeldung.com/java-8-date-time-intro

find current Date and day after tomorrow's date in java

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);

Java SWT DateTime: Determine day of Week

I have a DateTime widget with 3/9/2017. Based on the documentation for DateTime, I don't see a way to determine the day of the week. I'll eventually need a string parsed in this format "Wed Feb 22 14:57:34 UTC 2017" from the DateTime widget, but the first step is to get the day of the week. Is there a way to do this outside of making my own function? And if not, what would you recommend as the best approach for the function, since days of the week are not consistent to dates from year to year?
Let me know if you need any addition information.
Thank you!
Use java.util.Calendar:
Calendar c = Calendar.getInstance();
c.setTime(yourDate);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
if you need the output to be Tue rather than 3 (Days of week are indexed starting at 1), instead of going through a calendar, just reformat the string: new SimpleDateFormat("EE").format(date) (EE meaning "day of week, short version")
Documentation
tl;dr
LocalDate.of( 2017 , Month.MARCH , 9 )
.getDayOfWeek()
.getDisplayName( TextStyle.FULL , Locale.ITALY )
Or…
OffsetDateTime.now( ZoneOffset.UTC )
.format( DateTimeFormatter.RFC_1123_DATE_TIME )
java.time
The modern approach uses the java.time classes that supplanted the troublesome old date-time classes.
The DayOfWeek enum defines seven objects, one for each day of the week, Monday-Sunday.
The LocalDate class represents a date-only value without time-of-day and without time zone.
DayOfWeek dow = LocalDate.now().getDayOfWeek() ;
Generate a string of the localized name.
String output = dow.getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; // Or Locale.US etc.
To generate your longer string for a moment, use DateTimeFormatter to specify a custom pattern, use a built-in pattern, or automatically localize.
String output = OffsetDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.RFC_1123_DATE_TIME ) ;
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.

Conversion of java.util.Date to java.sql.Date truncates the time part

I am trying to save a java.util.Date from an application to my SQL Server database using JDBC.
When I convert the java.util.Date to a java.sql.Date using the method below, it truncates the time part.
java.sql.Date javaSqlExpiryDate = new java.sql.Date(javaUtilExpiryDate.getTime());
System.out.println("javaUtilExpiryDate: " + javaUtilExpiryDate.toString());
System.out.println("javaSqlExpiryDate: " + javaSqlExpiryDate.toString());
The Console window reports the output as:
javaUtilExpiryDate: Thu Sep 01 18:19:08 IST 2016
javaSqlExpiryDate: 2016-09-01
How do I get it to retain the time part as well?
Yes, that's the expected and documented behavior.
Quote from the JavaDocs
To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated.
If you want to keep the time, you need to use java.sql.Timestamp (especially if the column in the database is defined as datetime).
Just change your import from java.sql.Date TO java.sql.Timestamp
tl;dr
myPreparedObject.setObject(
1 ,
myJavaUtilDate.toInstant() // Convert legacy object to modern java.time object, `Instant`.
)
Details
The other Answers are correct. The java.util.Date class represents a date and a time-of-day in UTC. The java.sql.Date represents only a date, without the time-of-day. Well, actually, the java.sql.Date pretends to represent only a date but actually, as a badly-designed hack, subclasses the java.util.Date class and therefore does have a time-of-day. Confusing? Yes. One of many reasons to avoid these awful old legacy classes.
Now we have a better way, the java.time classes.
java.time
In the old days you would convert your java.util.Date object to a java.sql.Timestamp.
Now, with a JDBC driver supporting JDBC 4.2 and later, you can send your java.time objects directly to/from the database. No need for either the java.util nor java.sql classes, just stick with java.time classes.
If you have to interface with old code using java.util.Date, convert to java.time.Instant using new methods added to the old classes.
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).
Instant instant = myJavaUtilDate.toInstant() ;
Exchange an Instant with the database via PreparedStatement::setObject and ResultSet::getObject.
myPreparedStatement.setObject( … , instant ) ;
And…
Instant instant = myResultSet.getObject( … , Instant.class ) ;
To see this moment through some other time zone than UTC, apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
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 Calendar timezone converting to GMT problem

I have one Calendar object which is as per the user's time zone which may be PST etc, now i want to convert the same to GMT and retain the time i.e. is the calendar initially was set # 00:00:00 at PST it should be converted to 08:00:00 after the conversion taking into consideration the time/date difference . Can someone provide me some help on this.
Appreciate the help in advance.
Thanks,
Vaibhav
Just create a new Calendar in GMT, set the time in that calendar to the same as the original calendar, and you're done:
gmtCalendar.setTime(userCalendar.getTime());
That should be fine, as the getTime() call returns the instant in time (i.e. a java.util.Date with no associated time zone).
As ever though, if you're doing any significant amount of date/time work in Java you should strongly consider using Joda Time instead.
tl;dr
( ( GregorianCalendar ) myCal ) // Cast from a general `Calendar` to specific subclass `GregorianCalendar`.
.toZonedDateTime() // Convert from troublesome legacy class to modern java.time class, `ZonedDateTime`.
.toInstant() // Extract a UTC-specific value, an `Instant` object.
java.time
The modern approach uses java.time classes.
Convert your legacy Calendar object (if GregorianCalendar) to a ZonedDateTime. Call new conversion methods added to the old classes.
GregorianCalendar gc = ( GregorianCalendar ) myCal ;
ZonedDateTime zdt = gc.toZonedDateTime() ;
Now extract an Instant, a value always in UTC. You can think of it this way conteptually: ZonedDateTime = ( Instant + ZoneId )
Instant instant = zdt.toInstant() ;
For more flexibility such as generating strings in various formats, convert to an OffsetDateTime object.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
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.
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?
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.

Categories