Datetime Parsing - Unable to get back original value - java

DateTimeFormatter DATEFORMAT = ISODateTimeFormat.dateTimeNoMillis();
String testDate = "2013-10-26T04:23:14-08:00";
System.out.println(testDate);
System.out.println(DATEFORMAT.parseDateTime(testDate).toString(DATEFORMAT));
Output:
2013-10-26T04:23:14-08:00
2013-10-26T05:23:14-07:00
Why are outputs off by around an hour ? Is there any other parameter I need to specify for converting DateTime back to string ?
Any help is much appreciated.

I'm assuming this is using the joda-time library. As the comments above suggest, it's a TZ issue. You can easily convert any of the times into the TZ of your choice or UTC through a method call on the DateTime object. Something along the lines of:
dt.withZone(DateTimeZone.UTC);
You're getting different results since the default behavior is to print the DateTime in the system's current timezone.

Related

Date time conversion in Java8

I tried searching across the web, but unable to find a suitable answer and hence posting here.
I am calling another API which gives me the date-time like
"2022-02-05T17:13:20-06:00[America/Chicago]"
I would like to convert this to a format like
"2022-02-05T17:13:20.000Z" (I am unsure what the milli-second will turn out as)
Could someone help me achieve this?
I am unable to get any example for this specific conversion scenario!!!
Regards,
Sriram
For the sample values given getting to a UTC timestamp should be something like
ZonedDateTime.parse("2022-02-05T17:13:20-06:00[America/Chicago]").toInstant().toString()
The datetime value including the timezone is the canonical representation of a ZonedDateTime and therefore can be parsed as such.
Instant is a UTC timestamp that prints in the form of 2022-02-05T23:13:20Z
You could take more influence on the behavior using a DateTimeFormatter - but since both input and output seem to be standard formats it does not seem necessary.
Here below is a code snippet that I was able to generate....
But, I am unsure of that is correct. Please let me know if you feel anything is incorrect.
String requestTime = "2022-02-05T17:13:20-06:00[America/Chicago]";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX'['VV']'");
ZonedDateTime zonedDateTime = ZonedDateTime.parse(requestTime, formatter);
zonedDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"));
System.out.println(zonedDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")));

How to create proper DateTimeFormatter Pattern

I am trying to create a DateTimeFormatter object with a pattern to fit this expression of time: 2016-07-22T00:00:00.000-05:00. I am trying to create a DateTime object using the DateTimeFormatter class with the above input string.
I have tried many different versions of the below expression but am currently getting stuck at the timezone piece "-05:00" where I'm getting the error on my junit test case:
java.lang.IllegalArgumentException: Invalid format: "2016-07-22T00:00:00.000-05:00" is malformed at "-05:00"
The current format pattern that I am using is:
yyyy-MM-dd'T'HH:mm:ss.SSSZ
I have also tried:
yyyy-MM-dd'T'HH:mm:ss.SSSTZD
yyyy-MM-dd'T'HH:mm:ss.SSSZZZ
yyyy-MM-dd'T'HH:mm:ss.SSSz
yyyy-MM-dd'T'HH:mm:ss.SSSzzz
yyyy-MM-dd'T'HH:mm:ss.SSS'TZD'
I am running on Java 7 so I am not sure if that is causing an issue as well.
In order to achieve what you wish, you can utilize the static method "ofPattern" in the DateTimeFormatter class. This method returns a DateTimeFormatter object.
And as shown by tnas, you could use the following date and time format string:
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
DateTimeFormatter test = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
I tested the code and it compiles.
Late to the party, but you have to include some timezone information in your timestamp string. Otherwise it would be undefined from which timezone you'll want to substract your offset of five hours.
Assuming that you'll want to parse a timestamp which is 5 hours behind UTC, your string should read
2016-07-22T00:00:00.000Z-05:00
Note the 'Z' before the -05:00 part, which is short for "UTC"
DateTimeFormatter from "yyyy-MM-dd'T'HH:mm:ssX" worked for me.
The API's javadoc describe the patterns: https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
I've tested this code:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
Date date = new Date();
System.out.println(sdf.format(date));
The output was:
2016-08-22T18:34:26.604-03:00

Joda ISODateTimeFormat not using timezone in String

I have a two part issue, or maybe its two different ways to solve this. I receive an ISO string like 2015-11-17T17:10:24-0800. The end goal is to display the string as 11/17/15 5:10 PM in some HTML generated by some Freemarker. The string I receive could be in any timezone, but I always need to display the string in its local timezone as shown above. Currently, our code was just taking the string and passing it into the template and coverting as such:
<#assign mydate = obj.mydate?datetime("yyyy-MM-dd'T'HH:mm:ssz")?string.short>
This is no longer good since I believe Freemarker is using the system's local timezone and now we are getting more than one timezone. I see there is an iso method in freemarker. So I try
<#assign order_date = order.order_date?iso("yyyy-MM-dd'T'HH:mm:ssz")>
but I keep getting error:
For "?iso" left-hand operand: Expected a date, but this evaluated to a string
Ok I need a date. Working with Joda, I try and create a datetime object by:
DateTime dateTime = ISODateTimeFormat.dateTimeNoMillis().parseDateTime("2015-11-17T17:10:24-0800");
But that appears to use my local timezone as well and shows 2015-11-17T20:10:24.000-05:00. I know I could do withZone(...) but I dont know the zone other than the -0800 or whatever zone is passed at the end of the string. So I'm at a loss of what to do now. Oh, and I cannot change the format of the string I receive.
DateTime dateTime = ISODateTimeFormat.dateTimeNoMillis().withOffsetParsed().parseDateTime("2015-11-17T17:10:24-0800");
This will create a DateTime with a fixed timezone offset of -08:00.
May require a little more work, but you could always use the DateTimeFormatterBuilder to create your own custom display for the Date Time. This way you could drop the TimeZone if you care to and render it for within that TimeZone or render locally.

Convert String to Date in java - Time zone

I have a String, 2013-10-07T23:59:51.205-07:00, want to convert this to Java date object. I am getting parsing error.
date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse("2013-10-07T23:59:51.205-07:00");
try
date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
.parse("2013-10-07T23:59:51.205-0700");
The Z is not a literal and the timezone does not have a colon
See the examples at http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
If java7 is being used then Z can be replaced with X and the timezone can have a colon
Z shouldn't be inside quotes. I don't think Z would work for your given timezone. Before Java 7, I guess there wasn't any format to parse ISO 8601 format timezone with colon in between. You should use -0700 instead.
However, from Java 7 onwards, you have an option for parsing ISO 8601 format timezone using X instead of Z. See javadoc for SimpleDateFormat. Just use the following format:
// This would work from Java 7 onwards
date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX")
.parse("2013-10-07T23:59:51.205-07:00");
Your pattern is wrong, you should use the following:
date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
.parse("2013-10-07T23:59:51.205-07:00");
The 'X' indicates the Time zone in the ISO 8601 format as expressed in your String here: '.205-07:00'
For more information read the doc: SimpleDateFormat
Use this trick to parse ISO8601 datetime format. I admit have not tried this with millisecond part within a string value maybe it gives you an extra headache. This works for Java6.
import javax.xml.bind.DatatypeConverter;
Calendar cal = DatatypeConverter.parseDateTime(strDatetime);
If am remembering correct cal instance may not use a system-default timezone. Its initialized to the origin string value timezone. If you want instance to use system timezone you can do this conversion.
long ts = cal.getTimeInMillis();
cal = Calendar.getInstance();
cal.setTimeInMillis(ts);
You should use XXX for the format -07:00, instead of Z and X.
Date sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
.parse("2013-10-07T23:59:51.205-07:00");
Look at the example of this docs.
The problem is that -07:00 is not a valid Time zone . The Time Zone should have this format, for example something like -0800.

Java - Creating a Calendar without a TimeZone

I would like to start by saying that I've read several threads similar to this one, but none of them really solved my problem.
I would also like to state that I've tried to use SimpleDateFormat and joda.DateTime without any success.
The problem is the following:
I have a Calendar object that holds the information about a specific date: 2008-04-30T00:00:00Z
When using the calendar.getTime() method I can get different results because I know that that method is looking for the local value
Thus:
UK: 2008-04-30T01:00:00.000+0100
US: 2008-04-30T20:00:00.000-0400
But I would like to get a Date object that holds just the Date and Time values "2008-04-30T00:00:00" ignoring completely any timezone.
How can I do that?
As I mentioned before I tried to use
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
but I always end up with the same results.
Any help would be really appreciated
Cheers.
Found out that you can clear the Timezone by using code below:
Calendar cal = Calendar.getInstance();
cal.clear(Calendar.ZONE_OFFSET);
Calendars and Dates mean nothing without a TimeZone.
Calendars and dates cannot exist without a timezone.
You can't ignore completely any timezone.
You can create a Calendar for Greenwich Mean Time (offset zero) like this:
TimeZone zone = TimeZone.getTimeZone("Etc/GMT");
Calendar cal = Calendar.getInstance(zone);
This represents a Date/Calendar that is only meaningful in the GMT timezone.
It sounds like you want a timestamp, which represents an instant in time.
As others have pointed out, Calendar and Date objects cannot exist without a time zone.
I believe you may want to use the LocalDateTime class introduced in Java 8 with the new time API:
LocalDateTime literal = LocalDateTime.of(2008, 4, 30, 0, 0, 0);
LocalDateTime parsed = LocalDateTime.parse("2008-04-30T00:00:00"); // ISO-8601 by default
Assert.assertEquals(literal, parsed);
Do you use a standard constructor for initializing Calendar? What if you used the constructor which allows to specify the time zone and locale?
protected Calendar(TimeZone zone, Locale aLocale)
Old, but still incorrect.
"When using the calendar.getTime() method I can get different results because I know that that method is looking for the local value"
That is a misconception. getTime() will get the Milliseconds only. Countet as GMT.
ONLY during formatting of the Output the time zone becomes relevant. Sind the original poster did not show the code, it can not be decided, where the error occurs.

Categories