Java 8, time is not being converted - datetime

I'm using Hibernate 5 & MySQL.
This is what is getting saved into the database: 2018-03-11 06:26:47.336 I don't think this is 24 hour format, but then how do I see AM/PM? And how do I save the time in 24 hour format?
Running SELECT ##global.time_zone; in MySQL shows me: +00:00 So I think I'm set for accepting UTC time? This is how I set my pojo's field for setting time:
Clock clock = Clock.systemUTC();
LocalDateTime userCreated = LocalDateTime.now(clock);
It accepts LocalDateTime. But what I get back from database when I query is: u1.getUserCreated(): 2018-03-11T01:26:47.336 And when I try to convert the time into zone specific, I get the below:
ZonedDateTime z1 = ZonedDateTime.of(u1.getUserCreated(), ZoneId.of("America/New_York"));
System.out.println("z1: " + z1);
// z1: 2018-03-11T01:26:47.336-05:00[America/New_York]
But it really should be: 9:26:47.336 PM (21:26:47.336) As you can see on this site: http://www.timebie.com/std/utc.php

You're just not converting correctly. Your LocalDateTime represents the wall-clock time in the UTC time zone. Not in the New York time zone. So yo need to transform it to a ZonedDateTime in UTC::
ZonedDateTime utcDateTime = u1.getUserCreated().atZone(ZoneOffset.UTC);
Then, if you want to get a ZonedDateTime for the same instant, but in the New York timezone, then, well, just do that:
ZonedDateTime newYorkDateTime = utcDateTime.withZoneSameInstant(ZoneId.of("America/New_York"));

Related

Java how to add time and date

Using JDK 1.8
I have Time in ms for a day (not since 1970) and I have a Date how do I add the two and create a datetime.
Thanks
Tried #Kikos soln does not produce correct result:
Somehow my orig time 930 hrs in this case changes to 9:40, the orig date itself should not have any time gets time (??) - so the addition math fails.
String testdate = "2015/10/25";
Date date = new SimpleDateFormat("yyyy/mm/dd").parse(testdate);
String timehrs= "930";
long ltime = Long.parseLong("930");
long hoursAsSeconds = (ltime / 100) * 60 * 60;
long minsAsSeconds = (ltime % 100) * 60;
long secondsOfDay = hoursAsSeconds + minsAsSeconds;
System.out.println("testdate : "+ testdate +", timehrs: "+timehrs+" ,secondsOfDay: "+secondsOfDay);
System.out.println("Orig Date time formatted: "+ new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(date));
Date dt = new Date(date.getTime() + secondsOfDay*1000);
System.out.println("New Date : "+ new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(dt);
testdate : 2015/10/25, timehrs: 930, secondsOfDay: 34200
Orig Date time formatted: 2015-10-25 12:10:00
New Date : 2015-40-25 09:40:00
Expected : 2015-10-25 09:30:00
Based on below by #Basil Bourque
long nanosOfDay = TimeUnit.MILLISECONDS.toNanos( secondsOfDay*1000 );
LocalTime lt = LocalTime.ofNanoOfDay( nanosOfDay );
ZoneId z = ZoneId.systemDefault();
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
System.out.println("ZonedDateTime zdt: "+ zdt);
ZonedDateTime zdt: 2015-10-25T09:30-07:00[America/Los_Angeles]
This is the correct answer: 2015-10-25T09:30
Question is convoluted
You say you have time of day as a count of milliseconds since midnight (apparently). Yet 930 would mean the time 00:00:00.930, not 09:30:00 as shown in your example data. I will follow your text rather than your example data.
java.time
You are using troublesome old date-time classes, now legacy, supplanted by the java.time classes. Forget you ever heard of java.util.Date and .Calendar.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
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.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
ISO 8601
The java.time classes use the ISO 8601 standard by default when parsing/generating strings representing date-time values. To make your input string standard, replace those slash characters with hyphens.
String input = "2015/10/25".replace( "/" , "-" );
LocalDate ld = LocalDate.parse( input );
By the way, this whole scheme you have been assigned is awkward, error-prone, and needlessly complicated. To serialize a date-time value for communication between systems, use the ISO 8601 string formats.
LocalTime
You say you have a count of milliseconds to represent the time of day as a count from midnight.
The LocalTime class offers factory methods to instantiate based on a duration of whole seconds and of nanoseconds. To get nanoseconds, simply multiply your milliseconds by one thousand. Better yet, let the TimeUnit enum do the work and make your code more self-documenting.
long millisOfDay = Long.parseLong( "930" );
long nanosOfDay = TimeUnit.MILLISECONDS.toNanos( millisOfDay ); // Same effect as: ( millisOfDay * 1_000L )
LocalTime lt = LocalTime.ofNanoOfDay( nanosOfDay );
ZonedDateTime
Now combine these two Local… objects along with a time zone to determine a point on the timeline. Was this date and time meant to be a moment in Montréal Québec, Paris France, Kolkata India, or Aukland New Zealand?
ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z );
See live code in IdeOne.com.
ld.toString(): 2015-10-25
lt.toString(): 00:00:00.930
zdt.toString(): 2015-10-25T00:00:00.930+13:00[Pacific/Auckland]
LocalDateTime
If your data came with no information about time zone, and you cannot safely assume the intended time zone by your business scenario, you are left with no better option than combining into a LocalDateTime object. But keep in mind that this value is ambiguous. This value is not a point on the timeline. This value represents potential points on the timeline which can only be determined with a time zone assigned for ZonedDateTime or a offset-from-UTC assigned for OffsetDateTime.
LocalDateTime ldt = LocalDateTime.of( ld , lt );
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 java.time.
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….
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.
something like:
Date dt = new Date(System.currentTimeMillis() + ms);
or
Date otherDate(....);
Date dt = new Date(otherDate.getTime() + ms);

How to check cutoff time before or after the current time instance?

Currently i am working with shipping condition. in this i will get cut off time against the company like (05.00 PM) .
Now i want to compare above time with current time whether it is before cut off time or after cut off time?
I have gone through all the link i can see only example with date. i could not find anything with time.
Please let me know or give a some clue so that i will sorted out.
This is What i have tried so far
String todayDate=LocalDate.now().toString("dd.MM.yyyy");
String s=todayDate+cutOffTime;//cutOffTime will get from DB
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("dd.MM.yyyy HH:mm a");
LocalDate despatchDate=LocalDate.now();
try {
Date cutoffDate=simpleDateFormat.parse(s);
if (cutoffDate.after(Calendar.getInstance().getTime())){
despatchDate.plusDays(1);
}
} catch (ParseException e) {
e.printStackTrace();
}
Java 8 date/time api
LocalDateTime currentDateTime = LocalDateTime.now();
LocalDate currentDate = LocalDate.now();
String cutOff = "05:00 AM";
DateTimeFormatter timeParser = DateTimeFormatter.ofPattern("hh:mm a");
LocalTime cutOffTime = timeParser.parse(cutOff, LocalTime::from);
LocalDateTime cutOffDateTime = LocalDateTime.of(currentDate, cutOffTime);
//After
cutOffDateTime.isAfter(currentDateTime);
//Before
cutOffDateTime.isBefore(currentDateTime);
//Compare
cutOffDateTime.compareTo(currentDateTime);
Time Zone
The Answer by Shiv V is going in the right direction, but is not spot-on. The answer ignores the crucial issue of time zone. The Local… types intentionally lose and ignore time zone information, that is their purpose. But we rarely want to lose time zone info.
Determining the date and time-of-day depends on time zone. For any given moment, the date and time can vary around the globe. A few minutes after midnight in Paris is a new day while still “yesterday” in Montréal.
The Instant class defines a moment on the timeline in UTC with a resolution of nanoseconds.
Instant now = Instant.now();
If the desired deadline is “5 PM tomorrow”, you must specify the time zone as the context. Apply a ZoneId to an Instant to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime zdtTomorrow = zdt.plusDays( 1 );
Now adjust to 5 PM.
LocalTime timeOfDayWhenDue = LocalTime.of( 5 , 0 );
ZonedDateTime zdtDeadline = zdtTomorrow.with( timeOfDayWhenDue );
You can compare using the isEqual, isBefore, and isAfter methods.
ZonedDateTime now = ZonedDateTime.now( zoneId );
boolean overdue = now.isAfter( zdtDeadline );
You could also convert the zoned date-times back to UTC. The ZonedDateTime objects and their respective Instant objects represent the same simultaneous moment on the timeline (same moment in history), but seen from the viewpoint of different time zones (America/Montreal versus UTC).
Instant instantDeadline = zdtDeadline.toInstant();
Instant instantNow = now.toInstant();
boolean overdue = instantNow.isAfter( instantDeadline );
If you want to communicate the deadline to a customer in India, adjust into another time zone. The date-time value will represent the same moment on the timeline but will display with a wall-clock time that has meaning for that customer.
ZoneId zoneId_Kolkata = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdtDeadline_Kolkata = zdtDeadline.withZoneSameInstant( zoneId_Kolkata );
If you do not specify time zones, the JVM’s current default time zone is applied implicitly, silently. Not good. For one thing, implicit assumptions make your code easy-to-misunderstand and makes bugs more difficult to pinpoint. Worse, the default can change at any time, when you deploy to a different computer, or even during runtime at any moment of your app’s execution! Better to always specify the desired/expected time zone. By the way, same goes for Locale.

Turn off timezone DST adjustment in VB.NET?

fellow programmers. Recently i got a problem when the DST applied to my asp.net application.
Originally, i got my datetime converter as follow:
Private Function ConvertTimezone(convertDatetime As DateTime, zoneID As String) As DateTime
Dim timeZoneInfo As TimeZoneInfo = System.TimeZoneInfo.FindSystemTimeZoneById(zoneID)
Dim dataTimeByZoneId As DateTime = System.TimeZoneInfo.ConvertTime(convertDatetime, System.TimeZoneInfo.Local, timeZoneInfo)
Return dataTimeByZoneId
End Function
Which is running smoothly as i am expected. However, when daylight saving started, all stuff seems to went to the wrong way AS I LIST THE OPTION TO SELECT AS UTC - 12 TO UTC + 12 by getting the standard time and convert it using the above code.
For example, the problem i am facing is the shift of hours, before DST, My UTC - 5 is from Atlantic standard time ,but after DST it returns UTC - 4 now as .NET CONVERT IT BY ITSELF. The dropdown has gone wrong since then.
Is there anyway to turn the DST adjustment off? or any other work around can complement the offset? (No other library is allowed ,sorry fellows..)
I worked it around by parsing the UTC + x value where x is the offset
Private Function ConvertTimezone(convertDatetime As DateTime, zoneID As String) As DateTime
Dim desttimeZoneInfo As TimeZoneInfo
Dim dataTimeByZoneId As DateTime
If Not zoneID.Contains("GMT") Then
desttimeZoneInfo = System.TimeZoneInfo.FindSystemTimeZoneById(zoneID)
dataTimeByZoneId = System.TimeZoneInfo.ConvertTime(convertDatetime, System.TimeZoneInfo.Local, desttimeZoneInfo)
Else
dataTimeByZoneId = System.TimeZoneInfo.ConvertTimeToUtc(convertDatetime, System.TimeZoneInfo.Local)
dataTimeByZoneId = dataTimeByZoneId.AddHours(Double.Parse(zoneID.Substring(3)))
End If
Return dataTimeByZoneId
End Function

Joda DateTime output unexpected difference from gmt

My code:
val pattern = "MM-dd-yy"
val t = DateTime.parse("07-01-86", DateTimeFormat.forPattern(pattern)).toDateTime(DateTimeZone.forID("GMT"))
val z = t.getMillis.asInstanceOf[Long]
println("ms= "+z) // expected output: 520560000000 actual output: 520578000000
Several online GMT date converters give a different millis output than DateTime. Anyone know why?
In your solution your local time zone is implicitly used when parsing the date time. You should use
val t = DateTime.parse("07-01-86", DateTimeFormat.forPattern(pattern).withZoneUTC())
to force the DateTime to be created in the UTC zone. Then, the millis is 520560000000. No need to execute toDateTime(DateTimeZone) on it any more.
Otherwise, with your construction
val t = DateTime.parse("07-01-86", DateTimeFormat.forPattern(pattern)).toDateTime(DateTimeZone.forID("GMT"))
the DateTime will be first created in your local TZ (ie. midnight of 07-01-86 in your TZ) and then "cast" to UTC, but preserving the timestamp (ie. it will be the same timestamp, but interpreted in UTC, so the time part and the day part will change depending on your local TZ offset).
Example (my TZ is +02:00):
DateTime.parse("07-01-86", DateTimeFormat.forPattern(pattern)) // --> 1986-07-01 00:00 (+02:00)
.toDateTime(DateTimeZone.forID("GMT")) // --> 1986-06-30 22:00 (UTC)
I assumed you are OK with using UTC over GMT but there's also
DateTimeFormat.forPattern(pattern).withZone(...)
where you can provide your desired zone.

.NET 2.0 DateTime UTC conversion

Why does the ToUniversalTime function have no effect here;
DateTime dt = new DateTime(2009,3,24,1,0,0,DateTimeKind.Local);
dt = dt.ToUniversalTime(); // convert BST to UTC ?
dt.ToString();
"24/03/2009 01:00:00" ... wrong?
Is the same as..
DateTime dt = new DateTime(2009,3,24,1,0,0,DateTimeKind.Utc);
dt = dt.ToUniversalTime(); // nothing to do, already utc
dt.ToString();
"24/03/2009 01:00:00" ... correct.
I expected there to be an adjustment to the ToString() value of the first example, where by the DateTime specified as Local would result in a corresponding TimeZone calculation upon the call to ToUniversalTime() and the time in the UK should have resulted in
"24/03/2009 00:00:00" as UTC.
However it appears like the specifying of the DateTimeKind in this way renders ToUniversalTime or ToLocalTime unable to make any calculation.
Are you in the UK by any chance? Although we are now in daylight saving time, the date you specify in your code is before this switched over, so local and UTC time in the UK are the same. If you specify April as your month, then you will see a one hour difference.
Cheers David M.
Not had my breakfast. Indeed, when I repeat the test with dates that elapse the BST summer-time threshold, the behaviour is of course correct.
DateTime dt = new DateTime(2009,4,24,1,0,0,DateTimeKind.Local);
dt = dt.ToUniversalTime(); // convert BST to UTC ?
dt.ToString(); // "24/04/2009 00:00:00" ... correct
And to confirm, the ToString() method appears to output based on the Kind property.

Resources