Joda time getting right time from dateTime - java

I have this simple code:
DateTimeFormatter formatter = DateTimeFormat.forPattern("HH:mm yyyy-MM-dd");
DateTime dateTime = formatter.withZone(DateTimeZone.forID("America/New_York")).parseDateTime("08:30 2015-06-01");
DateTime dateTime2 = formatter.withZone(DateTimeZone.forID("America/New_York")).parseDateTime("08:30 2015-12-01");
these are leap times. when I hit toString method, I got something like this:
2015-06-01T08:30:00.000-04:00
2015-12-01T08:30:00.000-05:00
which is correct, we can see UTC time - offset. But when I call getHourOfDay, I got 8 and not 4/3 as expected. What am I doing wrong? Please, share some advices here.

Well, from the Javadoc for DateTimeFormatter#withZone():
Returns a new formatter that will use the specified zone in preference to the zone of the printed object, or default zone on a parse.
So, you told the formatter to use the specific timezone on parsing AND output, and the input you gave it did NOT contain a timezone, so this is the expected result. In essence you said:
Here's a date string without timezone, parse it assuming America/New_York
Convert the date back to String, in the timezone America/New_York
This is what it did.

Related

Scala - How to convert LocalDateTime to ZonedDateTime formatted without GMT postfix?

I wanted to get the LocalDateTime in GMT so wrapped it with ZonedDateTime.
But gmtZoneTime is returned in the following format: 2019-10-29T00:00Z[GMT] While I need it to be: 2019-10-29T00:00:00.000+0000
How should I properly convert localDateTime into the GMT ZonedDateTime?
val currentDate:LocalDate = java.time.LocalDate.now
val localDateTime: LocalDateTime = currentDate.atStartOfDay
val gmtZoneTime: ZonedDateTime = localDateTime.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("GMT"))
You need to format the ZonedDateTime.
First approach would be to use predefined formatter like: java.time.format.DateTimeFormatter.ISO_OFFSET_DATE_TIME, however for GMT it shows 'Z' instead of '+0000' (default behaviour, other offsets are displayed like '+0100' etc.)
So the second one would be to create your own formatter like:
java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ")
and then use it to format ZonedDateTime like gmtZoneTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ"))
so you get a result like:
2019-10-28T23:00:00+0000
First your code is incorrect. When I ran it in my time zone (Europe/Copenhagen) just now, I got
2019-10-29T23:00Z[GMT]
I don’t think you intended 23:00 in GMT.
Second you may think of GMT or UTC as an offset (of zero from UTC), so it is more correct to use an OffsetDateTIme than a ZonedDateTime for the time. This also eliminates your unwanted suffix. In Java (it’s all I can write):
LocalDate currentDate = LocalDate.now(ZoneOffset.UTC);
OffsetDateTime gmtZoneTime = currentDate.atStartOfDay(ZoneOffset.UTC)
.toOffsetDateTime();
System.out.println(gmtZoneTime);
Output when running just now:
2019-10-30T00:00Z
Edit: You can safely regard UTC and GMT as synonymous since java.time does that (even though strictly speaking they may differ by up to a second).
I assumed you also wanted the date in UTC, so passed this as argument to LocalDate.now(). If you want the date in some other time zone, pass that time zone to LocalDate.now() so that it is clear from the code what you get.
If you want that specific format in your question, pezetem is correct in the other answer that you need to format into a string:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxx");
String formattedGmtTime = gmtZoneTime.format(formatter);
System.out.println(formattedGmtTime);
2019-10-30T00:00:00.000+0000
It seems wordy to me, though. I’d at least leave out the milliseconds since we know they are 0, probably the seconds too. Said without knowing your exact business case.
Link: Difference between UTC and GMT

Extract time zone from jodatime DateTime

I receive a datetime string containing an ISO8601 datetime, like this "2001-07-04T12:08:56.235-07:00", then this string is parsed to a jodatime datetime object this way new DateTime("2001-07-04T12:08:56.235-07:00"), and after that it is converted to a string again using a variable formatter pattern passed by arguments, but when that happens, no timezone is used, so the system's default timezone is being used. What I want is to extract the timezone (or offset) from the first given date, and use it to print it accordingly. Is it possible?
Thanks beforehand!
Don't use new DateTime("..."). Use DateTime.parse("...").
See difference:
DateTime dateTime1 = new DateTime("2001-07-04T12:08:56.235-07:00");
System.out.println(dateTime1);
System.out.println(dateTime1.getZone());
DateTime dateTime2 = DateTime.parse("2001-07-04T12:08:56.235-07:00");
System.out.println(dateTime2);
System.out.println(dateTime2.getZone());
Output (I'm in eastern US)
2001-07-04T15:08:56.235-04:00
America/New_York
2001-07-04T12:08:56.235-07:00
-07:00
As you can see, using new converts to default time zone, while using parse retains the given time zone.

SimpleDateFormat parses a string to wrong time

I run the following code:
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
try{
Date date = sdf.parse("03-28-2003 01:00:00");
System.out.print(date.toString());
}
catch(Exception e){
//do something
}
The result of the parsing is this date: 2003-03-28T02:00:00.000+0300
One hour is added.
When I change the year/day/hour to any other valid number, I get the correct time, no extra hour is added. If I only change the minutes or the seconds I still get the added hour.
Can anyone tell me why this happens?
EDIT:
This is related to when daylight saving time is applied in the timezone my program runs on- UTC+02:00.
In this timezone the clock changed on 2003-03-28. that's why an hour was added, as it was suggested by the comments and answer below.
I used the code suggested in the answer to parse my date and the parsing worked! The date is parsed correctly, the extra hour isn't added.
Finding out exactly what your code does is complicated by the fact that not only SimpleDateFormat.parse() may depend on the default time zone of the computer (and does in this case where the pattern does not include time zone), also Date.toString() depends on the default time zone. However, I understand that you want to interpret the date string in UTC, so I will concentrate on getting the parsing right and not worry so much about what’s printed.
Feek is correct in the comment that setting the time zone of the SimpleDateFormat to UTC will get you what you want, for example:
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
With this line added before try I get this output on my computer:
Fri Mar 28 02:00:00 CET 2003
2 am. CET agrees with 1 UTC, so now the parsing is correct.
Allow me to add that if you can use the Java 8 date and time classes, I find the corresponding code somewhat clearer:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd-yyyy HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse("03-28-2003 01:00:00", formatter);
OffsetDateTime utcDateTime = dateTime.atOffset(ZoneOffset.UTC);
System.out.println(utcDateTime);
The point is not that it’s shorter, but that you don’t get easily in doubt about what it does and don’t easily get time zone or DST problems. An added benefit is that the output is also as expected:
2003-03-28T01:00Z
Now it’s evident that the time is correct (Z means Z or Zulu or UTC time zone, it’s got more than one name).
If for some reason you absolutely need an oldfashioned java.util.Date object, that is not difficult:
Date date = Date.from(utcDateTime.toInstant());
This gives the same date as we got from sdf.parse() with UTC time zone.

Joda DateTime doesn't display correct time for a specific timezone

In a chat application, the server gave me this info regarding on the date that the message was created
2015-05-04 09:56:27
DateTime instance gives me this 2015-05-04T09:56:27.000+08:00
What I wanted to display on the chat bubble is this format
hh:mm a
My code doesn't seem to display the hours and minutes I wanted, instead it displays the hours and minutes in UTC
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
DateTime dt = formatter.parseDateTime(strDate);
String str = String.format("%s:%s %s",
dt.toString("hh"),
dt.toString("mm"),
dt.toString("a")
);
it displays like this 09:56 am instead of 5:56 pm. It seems like the +8 offset wasn't counted. I have tried the withOffsetParsed and it doesn't work too
DateTimeFormatter df = formatter.withOffsetParsed();
DateTime dt2 = df.parseDateTime(strDate);
Is there anything I missed?
If DateTime outputs 09:56:27.000+08:00, then that is your local time- and the UTC time is 1:56am.
However, if your expectation that this should output 5:56pm is correct, something else is wrong. The server is giving you a timestamp without a timezone specified, which is a bad API. Presumably this time should be interpreted as UTC?
Try adding .withZoneUTC() to the creation of the DateTimeFormatter. This will make it interpret the time fields of the string as UTC and should produce a DateTime of 09:56:27.000Z. You'll then need to convert this is a DateTime in your local timezone to display it, by calling .withZone(DateTimeZone.getDefault()) (or whatever means you have to get the appropriate timezone for the user, for example)
(You could be pedantic and call parseLocalDateTime to get a LocalDateTime since that is what the server is sending, but personally I'd just encapsulate the UTC rule into the formatter and pull a full DateTime straight out)

Time Zone off by 10 hours in Joda-Time

I need to parse a string into a Joda-Time DateTime (or java.util.Date.) This is an example of the string I'm getting:
eventDateStr = 2013-02-07T16:05:54-0800
The code I'm using:
DateTimeFormatter presentation = DateTimeFormat.forPattern("yyyy-MM-dd kk:mm:ssZ");
DateTime eveDate = presentation.parseDateTime(eventDateStr);
The above throws this exception:
Invalid format: "2013-02-07T16:05:54-0800" is malformed at "T04:03:20-0800"
So I'm parsing the 'T' out of there:
eventDateStr = eventDateStr.indexOf("T") > 0 ? eventDateStr.replace("T", " ") : eventDateStr;
and trying again. This time no exception but the time zone is off:
2013-02-08T02:05:54.000+02:00
Note the difference: in the original string the timezone is '-0800' and here it's '+02:00'. This in turn changes the entire date, which is now a day later.
What am I doing wrong?
Call the method withOffsetParsed on the DateTimeFormatter object to get a DateTimeFormatter that keeps the time zone parsed from the String, instead of offsetting it to the local time zone.
Regarding why T is shown when you print out the DateTime, Basil Bourque has a nice explanation in the comment below.
Regarding T, a DateTime is not a string nor does it contain a string. A DateTimeFormatter instance can generate a string representation of the date, time, and time zone information stored within a DateTime. When you invoke the toString method on a DateTime (either implicitly or explicitly), a built-in formatter based on ISO 8601 is used automatically. That formatter uses YYYY-MM-DDTHH:MM:SS.ssssss+00:00 format.

Categories

Resources