Epoch is not epoch if do a new Date(0L). Why? - java

My problem is pretty straigtforward explained :
if I do this :
public class Main {
public static void main(String[] args) throws Exception {
Date d = new Date(0L );
System.out.println(d);
}
}
I get the following output : Thu Jan 01 01:00:00 CET 1970
According to the doc, I was expecting : Thu Jan 01 00:00:00 CET 1970
I would like was going wrong...
EDIT :
Indeed, I read the doc too fast. I should have Thu Jan 01 00:00:00 GMT 1970
So, how can I force the use of GMT, and ignore all local time ?
Edit, Solution :
public static void main(String[] args) throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("H:m:s:S");
SimpleTimeZone tz = new SimpleTimeZone(0,"ID");
sdf.setTimeZone(tz) ;
Date d = new Date(0L );
System.out.println( sdf.format(d));
}

The Epoch is defined as 00:00:00 on 1970-1-1 UTC. Since CET is UTC+1, it's equal to 1AM your time.
If you look at the Date(long) constructor, you'll see that it expects the value to be the number of milliseconds since the epoch, UTC:
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.
Regarding your desire to force GMT instead of your local time zone: In short, the Date instance always uses GMT. If you just want to format the output String so that it uses GMT have a the DateFormat class, and specifically, its setTimeZone() method.

This might be related to your locale settings. Assuming you're French and not French-Canadian, it would seem as if your timestamp is being treated as timestamp without timezone, and the Date constructor attempts to correct for this, adding an hour to the date.
If this is undocumented behavior or not, I cannot tell you.
Edit: Read error: CET != UTC :/
So yeah, Locale time zone.
Reedit: For utter and absolute clarity.
Output: Thu Jan 01 01:00:00 CET 1970
Your expected output: Thu Jan 01 00:00:00 CET 1970
Actual expected output: Thu Jan 01 00:00:00 GMT 1970 ( ≡ Thu Jan 01 01:00:00 CET 1970)

tl:dr
Instant.EPOCH
.toString()
1970-01-01T00:00:00Z
Date::toString lies
You've learned one of the many reasons to avoid using the java.util.Date/Calendar classes: a Date instance has no time zone information, yet it's toString method uses your default time zone when rendering a string for display. Confusing because it implies the Date has a time zone when in fact it does not.
Avoid Date/Calendar
Instead of Date/Calendar, you should be using Joda-Time or the new Java 8 classes, java.time.* from JSR 310.
java.time
Use the Instant class as the equivalent of Date, a moment on the timeline in UTC.
Instant.now()
For the epoch reference date, use the constant.
Instant.EPOCH.toString()
1970-01-01T00:00:00Z
If by "ignore all time" you mean that you really want a date-only value without time-of-day, use the LocalDate class.
LocalDate.ofEpochDay( 0L )
1970-01-01
Joda-Time Example
Update: The Joda-Time project is now in maintenance mode with the team advising migration to the java.time classes.
In Joda-Time, a DateTime instance does indeed know its own time zone. You can use a formatter to create string outputs in other time zones, if desired.
Here's your code aiming at the Unix time Epoch, but using Joda-Time 2.3.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
DateTimeZone timeZone_Paris = DateTimeZone.forID( "Europe/Paris" );
DateTime epochParis = new DateTime( 0L, timeZone_Paris );
DateTime epochUtc = new DateTime( 0L, DateTimeZone.UTC );
Dump to console…
System.out.println( "epochParis: " + epochParis );
System.out.println( "epochUtc: " + epochUtc );
When run…
epochParis: 1970-01-01T01:00:00.000+01:00
epochUtc: 1970-01-01T00:00:00.000Z
Convert To UTC/GMT
So, how can i force the use of GMT, and ignore all local time ?
To use UTC/GMT (no time zone offset), either:
Convert a DateTime to another instance with a different time zone(Joda-Time makes things immutable for thread-safety, so we don't actually convert, we create new instances based on old ones.)
Use a formatter to create strings displayed for a specified time zone.
// To use UTC/GMT instead of local time zone, create new instance of DateTime.
DateTime nowInParis = new DateTime( timeZone_Paris );
DateTime nowInUtcGmt = nowInParis.toDateTime( DateTimeZone.UTC );
Dump to console…
System.out.println( "nowInParis: " + nowInParis );
System.out.println( "nowInUtcGmt: " + nowInUtcGmt );
When run…
nowInParis: 2013-12-22T08:40:01.443+01:00
nowInUtcGmt: 2013-12-22T07:40:01.443Z

CET is one hour ahead of GMT, which is the time zone used to define the Epoch.

Related

Parse String date of format yyyy-MM-dd to java.util.Date of format yyyy-MM-dd

We are using Java8 in our project.I have startDate in String format "2021-12-31" which I am receiving from from an 3RD party.
I have to pass it to our consumer via our model.Model accepts java.util.Date and the format should be yyyy-MM-dd.
I wrote the below code:
String strDate="2021-12-31";
DateFormat df=new SimpleDateFormat("yyyy-MM-dd");
java.util.Date parsedDate=(Date)df.parse(strDate);
Expected output : parsedDate = 2021-12-31
Actual Output: parsedDate= Tue Dec 07 00:00:00 GMT +5.30 2021.
Please help.
No, Tue Dec 07 00:00:00 GMT +5.30 2021 could not be the result of your code. Even accounting for time zone issues, the result could not be different by weeks. Please take more care when posting here, to not waste people's time.
The actual results of your code will be something more like the following. See for yourself.
Fri Dec 31 00:00:00 GMT 2021
Or, setting the JVM’s current default time zone to Asia/Kolkata:
Fri Dec 31 00:00:00 IST 2021
Notice that those two results are different moments, several hours apart. The day starts earlier in India than at UTC/GMT prime meridian. So the results of this code vary by the current default time zone — not good!
java.time
You are using terrible date-time classes that were years ago supplanted by the modern java.time classed defined in JSR 310.
Your input string complies with the ISO 8601 standard used by default in the java.time classes when parsing/generating text. So no need to specify a formatting pattern.
For a date-only value, without time of day, and without time zone or offset-from-UTC, use LocalDate.
LocalDate ld = LocalDate.parse( "2021-12-31" ) ;
You said:
Model accepts java.util.Date and the format should be yyyy-MM-dd
Well, (a) that is unfortunate, (b) a Date object does not have a "format", it has a date-time value rather than text, and (c) a java.util.Date represents a moment, a specific point on the timeline rather than a date-only. A Date object represents a date with time-of-day as seen in UTC (an offset from UTC of zero hours-minutes-seconds).
The best solution is to fix your design to use proper types.
If you cannot fix the faulty design and must employ a hack, then perhaps you could use the first moment of the day on that date as seen in UTC.
ZonedDateTime zdt = ld.atStartOfDay( ZoneOffset.UTC ) ;
Instant instant = zdt.toInstant() ;
Convert from modern class to legacy class by calling new conversion methods added to the old classes.
java.util.Date d = Date.from( instant ) ;
Dump to console.
System.out.println( "ld.toString(): " + ld ) ;
System.out.println( "zdt.toString(): " + zdt ) ;
System.out.println( "instant.toString(): " + instant ) ;
System.out.println( "d.toString(): " + d ) ;
See this code run live at IdeOne.com.
ld.toString(): 2021-12-31
zdt.toString(): 2021-12-31T00:00Z
instant.toString(): 2021-12-31T00:00:00Z
d.toString(): Fri Dec 31 00:00:00 GMT 2021

Get CST current date at 00:00:00 time in java

I need the current date in following format at 00:00:00 CST time.
Like say current date is July 9 2021 Then I need that date along with 00:00:00 time.
Expected Output:
Fri Jul 09 00:00:00 CST 2021
Current code:
LocalDateTime date= LocalDateTime.now().with(LocalTime.MIN);
Date dayStart= Date.from(date.atZone(ZoneId.systemDefault()).toInstant());
Output of CurrentCode: Fri Jul 09 00:00:00 UTC 2021
Current code picking servertime /GMT which is 5hrs ahead of CST.
Example: 09AM GMT is 14 CST/2PM CST
I have tried to set calendar to 00:00:00 and setTimeZone to America/New_York. But while am returning output as calendar.getTime() give some other time rather than giving CST 00:00:00.
Tried : #scheduled(zone="America/New_york" ) --Not Working.
There are two good answers. My suggestion only differs in the detail (which is where the devil is, according to some).
First of all you should avoid using the Date class if you can. You are already using java.time, the modern Java date and time API, (LocalDateTime, LocalTime, ZoneId). You are getting all the functionality that you need from java.time. So I am assuming that you are only converting to Date because you need a Date for some legacy API that you cannot afford to upgrade to java.time just now.
Instant startOfDay = ZonedDateTime.now(ZoneId.systemDefault())
.truncatedTo(ChronoUnit.DAYS)
.toInstant();
Date oldfashionedDate = Date.from(startOfDay);
System.out.println(oldfashionedDate);
.truncatedTo(ChronoUnit.DAYS) throws away the time part of the ZonedDateTime, usually leaving us with 00:00:00 on the same day in the same time zone.
Edit:
I want America Chicago time CDT
Running the above code with the default time zone of the JVM set to America/Chicago gave:
Mon Jul 12 00:00:00 CDT 2021
Getting the right Date value and getting the expected printed output are two different things since Date.toString() picks the default time zone of the JVM and uses it for rendering the string to be returned. This behaviour may give surprises. There is no way to persuade Date.toString() to use a different time zone, so the above output only comes through setting the default time zone.
Original text: There are a lot of time zones referred to as CST and there’s no way I can be sure which one you intended (and i believe that the comments stating that America/New_York is not one of them are correct). However, the only one that I could persuade the old-fashioned Date class to abbreviate CST was China Standard Time. Running the above code in Asia/Shanghai time zone gave this output:
Sat Jul 10 00:00:00 CST 2021
It looks right to me. Since you asked your question it has become Saturday 10th in China Standard Time time zone.
Any time zone will work for getting the right Date value, the start of the day in that time zone. You also wanted an abbreviation of CST in the printed output. Time zones that did not work for this include:
Australia/Adelaide time zone. Output was Sat Jul 10 00:00:00 ACST 2021. So even though Australian Central Standard Time is sometimes abbreviated just CST, Date chose ACST.
America/Havana. Cuba uses Cuba Daylight Time at this time of year, so CDT is output.
America/Winnipeg and American/Chicago. North American Central Time uses daylight saving time too, so here too CDT is output.
In any case, you know which time zone you intended, so I am leaving to you to pick.
The easiest way to change the timezone is to use System.setProperty("user.timezone", "America/New_York"); in Java NOTE:: America/New_York is not CST
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;
class DateAndTimeZoneFormatter {
public static void main(String[] args) {
System.setProperty("user.timezone", "America/New_York");
LocalDateTime date = LocalDateTime.now().with(LocalTime.MIN);
Date dayStart = Date.from(date.atZone(ZoneId.systemDefault()).toInstant());
System.out.println(dayStart);
}
}
You could try to use a ZonedDateTime with a specific ZoneId:
public static void main(String[] args) {
// define the zone to be used
ZoneId americaChicago = ZoneId.of("America/Chicago");
// then take the date of today
ZonedDateTime nowInChicago = ZonedDateTime.of(
LocalDate.now(), // today
LocalTime.MIN, // start of day
americaChicago // zone
);
// define an output format
DateTimeFormatter dtf = new DateTimeFormatterBuilder()
.appendPattern("EEE MMM dd HH:mm:ss")
.appendLiteral(' ')
.appendZoneText(TextStyle.SHORT)
.appendLiteral(' ')
.appendPattern("uuuu")
.toFormatter(Locale.ENGLISH);
// then print the formatted String representation
System.out.println(nowInChicago.format(dtf));
}
This outputs
Fri Jul 09 00:00:00 CDT 2021
Downsides:
this won't fully match your expected output due to CST not being applied because it is daylight saving time. Therefore, CDT will be the output.
taking a Date.from this ZonedDateTime.toInstant() will affect the values:
Applying these two lines
Date sameNowInChicago = Date.from(nowInChicago.toInstant());
System.out.println(sameNowInChicago);
will output
Fri Jul 09 07:00:00 CEST 2021
on my machine because it is configured to have a ZoneId.of("Europe/Berlin"), which will be taken into account when printing a java.util.Date.
CEST ⇒ Central European Summer Time.

Java 8: Convert file time (milliseconds from 1970) to RFC 1123 format

This seems like it should be simple, but so far nothing I try is working. Basically I want to convert a file time in milliseconds from 1970 (the usual) to a TemporalAccessor and then to an RFC 1123 formatted string. However, while I can get examples that compile, I get runtime errors. For example:
// Just using 0 milliseconds time for quick and easy test
System.out.println(java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME.format(
FileTime.from(0, TimeUnit.MILLISECONDS).toInstant()));
results in
Exception in thread "main" java.time.temporal.UnsupportedTemporalTypeException:
Unsupported field: DayOfMonth
I have tried a few variations of this using different classes (Instant, LocalTime, Date), but I get the same result.
What is the proper way to do this?
UPDATE:
The original question has been technically answered and I realized I needed to be more specific. I had already 'successfully' converted milliseconds to a TemporalAccessor myself, however it didn't seem like this object was in usable state. I got a run time error when trying to use it to do what I really needed, which made me believe I hadn't created it properly. That something was missing. Either that or there is a bug in the RFC 1123 formatter.
UPDATE 2:
Thanks to Sleafar for posting a working answer.
Using his example I did it slightly differently since for some reason I really wanted a 'complete' TemporalAccessor to do stuff with. Here is a working example:
TemporalAccessor time = ZonedDateTime.ofInstant(Instant.ofEpochMilli(0),
ZoneId.systemDefault());
System.out.println(
java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME.format(time));
The Instant type doesn't contain timezone information. You can define a timezone for the formatter like this:
System.out.println(java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME
.withZone(ZoneId.systemDefault()).format( FileTime.from(0, TimeUnit.MILLISECONDS).toInstant()));
Edit:
Actually there are reasons to have formatters without an assigned timezone, as well as date/time representing classes. Consider the following example:
ZoneId ect = ZoneId.of(ZoneId.SHORT_IDS.get("ECT"));
DateTimeFormatter f1 = DateTimeFormatter.RFC_1123_DATE_TIME;
DateTimeFormatter f2 = f1.withZone(ect);
DateTimeFormatter f3 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
DateTimeFormatter f4 = f3.withZone(ect);
LocalDateTime ldt = LocalDateTime.of(2015, 07, 21, 0, 0, 0, 0);
ZonedDateTime zdt = ZonedDateTime.of(ldt, ect);
Instant ins = zdt.toInstant();
System.out.println(f1.format(ins)); // throws exception (1)
System.out.println(f2.format(ins)); // Tue, 21 Jul 2015 00:00:00 +0200
System.out.println(f3.format(ins)); // throws exception (2)
System.out.println(f4.format(ins)); // 2015-07-21T00:00:00
System.out.println(f1.format(zdt)); // Tue, 21 Jul 2015 00:00:00 +0200
System.out.println(f2.format(zdt)); // Tue, 21 Jul 2015 00:00:00 +0200
System.out.println(f3.format(zdt)); // 2015-07-21T00:00:00
System.out.println(f4.format(zdt)); // 2015-07-21T00:00:00
System.out.println(f1.format(ldt)); // throws exception (3)
System.out.println(f2.format(ldt)); // throws exception (4)
System.out.println(f3.format(ldt)); // 2015-07-21T00:00:00
System.out.println(f4.format(ldt)); // 2015-07-21T00:00:00
ZoneId hst = ZoneId.of(ZoneId.SHORT_IDS.get("HST"));
ZonedDateTime zdt2 = ZonedDateTime.of(ldt, hst);
System.out.println(f1.format(zdt2)); // Tue, 21 Jul 2015 00:00:00 -1000
System.out.println(f2.format(zdt2)); // Tue, 21 Jul 2015 12:00:00 +0200
System.out.println(f3.format(zdt2)); // 2015-07-21T00:00:00
System.out.println(f4.format(zdt2)); // 2015-07-21T12:00:00
Instant represents an actual point in time without referring to a specific location and therefore without a timezone. The exceptions (1) and (2) are raised because to represent the specific point in time the formatter needs a timezone to make the output readable for humans.
ZonedDateTime represents an actual point in time also assigned to a specific timezone. No problems at all to format them, but consider the last example. If you set a timezone in the formatter, you might get different results.
LocalDateTime doesn't represent an actual point in time. You can even assign a value which is invalid in some timezones, like when the clock is pushed forward 1 hour in case of daylight saving time. To get a real point in time you have to combine it with a timezone (like done in the example above). Exceptions (3) and (4) are raised, because the formatter wants to print a timezone value, which doesn't exist in this type.
I can't tell why the designers opted to discover the described problems at runtime instead of compile time. Maybe it would make the class hierarchy too complicated.
Milliseconds since 1970 is known as "epoch time", and Instant has the static method Instant.ofEpochMilli(long) to support creation from a long number of milliseconds. Conceptually Instant represents a single moment (long seconds + int nanoseconds) in "the standard Java epoch", so representing file time as an Instant is the correct JSR-310 way to do it.
FileTime also has a fromMillis(long) static method for the same purpose.
In this case, the conversion wasn't the problem—it was the lack of timezone as Sleafar identified first, as reflected in your edited question.
The conversion to Instant succeeds without problem. The problem is the formatter. Use ISO_INSTANT formatter instead of RFC_1123_DATE_TIME then you should go:
inst = Instant.now();
System.out.println(java.time.format.DateTimeFormatter.ISO_INSTANT
.format( inst ) );
--> 2015-07-20T21:11:53.001Z
If you really want to have RFC_1123 format, you have to declare a timezone.
Either append it to the formatter :
System.out.println(java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME
.withZone( ZoneOffset.UTC )
.format( inst ) );
or convert the Instant to a ZonedDateTime:
ZonedDateTime zdt = ZonedDateTime.ofInstant( inst, ZoneOffset.UTC );
System.out.println(java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME
.format( zdt ) );
--> Mon, 20 Jul 2015 21:11:53 GMT

How do I set a Calendar with TimeZone?

I have a timestamp that I am trying to put into a Date object, however when I use Calendar, I am running into a strange problem. I seem to be able to unable to create a Date object with the values I want:
public static void main(String args[]){
Date today = new Date();
int hour = 4, min=0, sec=0, ms=64;
Calendar cal = GregorianCalendar.getInstance();
cal.clear();
cal.setTimeZone(TimeZone.getTimeZone("EDT"));
cal.setTime(today);
cal.set(Calendar.HOUR_OF_DAY,hour);
cal.set(Calendar.MINUTE,min);
cal.set(Calendar.SECOND,sec);
cal.set(Calendar.MILLISECOND,ms);
System.out.println("Time is: "+cal.getTime());
}
This produces:
Time is: Mon Jan 13 23:00:00 EST 2014
which is not the result I am looking for.
However, if I comment out the 'setTimeZone' method call, I get the following result:
Time is: Tue Jan 14 04:00:00 EST 2014
This is the result that I am looking for but I am concerned that if I am running on a machine that is not running in the same time zone, I will not get consistent behavior.
This is the result that I am looking for but I am concerned that if I am running on a machine that is not running in the same time zone
it is the problem. The internal representation should be ok, but it prints on local timezone: representation differs from real content.
use SimpleDateFormat http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html and set TimeZone to see the date on the Zone desired.
The problem here is that Java does not know of the timezone "EDT" (Eastern Daylight Time). As a result, Calendar seems to be setting the timezone to GMT.
The timezone needed here is "America/New_York" or "EST5EDT". When either of these values are used, the correct result is produced.
The list of valid Time Zones can be obtained by calling TimeZone.getAvailableIDs()
It is unfortunate that no warnings are produced when the requested Time Zone is not found.
If you can do away with java.util.Date, you can use joda time API to conveniently set these values as desired:
For your query, you can set your already created Calendar instance as a constructor parameter to DateTime.
DateTime dt = new DateTime(cal);
System.out.println(dt.toDateTimeISO());
Output:
2014-01-14T04:00:00.064-05:00
Calendar.getTime() returns a java.util.Date object. Date objects do not know anything about timezones. The Date object that Calendar.getTime() returns does not know to what timezone the Calendar that it came from is set.
When you print a Date object (for example, by implicitly calling toString() object, as you are doing) it is formatted in the default time zone of the machine you are running it on.
If you want to print a Date in a specific timezone, use a SimpleDateFormat, and set the desired timezone on the SimpleDateFormat object. For example:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("EDT"));
// Will display the date that the calendar is set to in the EDT timezone
System.out.println(df.format(cal.getTime()));
Java Date objects represent the number of milliseconds seconds since January 1, 1970, 00:00:00 GMT due to the fact that the other methods are deprecated. The two ways to "view" a Date object directly are "getTime()" and "toString()" (using "dow mon dd hh:mm:ss zzz yyyy"). Therefore, you are formatting the GMT value to your local timezone.
When working with dates, it is best to think of them as GMT values, and then as a "formatting" exercise when viewing the date.
For comparison, here is that same kind of code but using Joda-Time 2.3.
Avoid the java.util.Date & .Calendar classes.
Never use three-letter codes for time zones. They are neither standardized nor unique. Instead use proper time zone names. In this case, use "America/New_York" or "America/Montreal".
// Use time zone names, such as from this slightly outdated list: http://joda-time.sourceforge.net/timezones.html
DateTimeZone timeZone = DateTimeZone.forID( "America/New_York" );
// Input.
int hour = 4, min = 0, sec = 0, ms = 64;
// Start with now, then adjust the time of day.
DateTime now = new DateTime( timeZone );
DateTime dateTime = now.withHourOfDay( hour ).withMinuteOfHour( min ).withSecondOfMinute( sec ).withMillisOfSecond( ms );
// If needed, translate to a java.util.Date for use with other classes.
java.util.Date date = dateTime.toDate();
Dump to console…
System.out.println( "now: " + now );
System.out.println( "dateTime: " + dateTime );
System.out.println( "date: " + date );
When run…
now: 2014-01-20T21:04:51.237-05:00
dateTime: 2014-01-20T04:00:00.064-05:00
date: Mon Jan 20 01:00:00 PST 2014

Java and Joda-Time: date wrong value

I'm getting a wrong date in Joda-Time when I try to parse a string date like this:
2013-11-20 18:20:00 +01:00
I'm expecting to obtain the following date:
Wed Nov 20 19:20:00 CET 2013
but I'm getting:
Wed Nov 20 18:20:00 CET 2013
I'm using Joda-Time and this is my code:
String dateString = "2013-11-20 18:20:00 +01:00";
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss Z");
DateTime temp = formatter.parseDateTime(dateString);
Date date = temp.toDate();
Expectations
Your expectation is wrong.
The "+01:00" means that time is one hour ahead of UTC/GMT. So, adjusting to UTC means subtracting an hour (17:20) rather than adding (19:20).
The "+01:00" has the same effect as saying CET (Central European Time), meaning one hour ahead of UTC/GMT. So…
2013-11-20 18:20:00 +01:00 = Wed Nov 20 18:20:00 CET 2013
…those are two different ways of stating the same time, same hour.
When I run your code here in United States west coast time, I get… (note the same hours)
temp: 2013-11-20T09:20:00.000-08:00
date: Wed Nov 20 09:20:00 PST 2013
j.u.Date Confusion
As the answer by Stroboskop said, you may be fooled by java.util.Date. The object itself does not have time zone information. Yet it's implementation of the toString() method uses the default time zone in rendering the text to be displayed. Confusing. One of many reasons to avoid using the java.util.Date/Calendar classes. In contrast, Joda-Time DateTime objects do indeed know their own time zone.
Specify Time Zone
Your real problem is an all too common one: Ignoring time zones. By not specifying a time zone, your default time zone was used. As you can see above, my default time zone is different than yours, so I got different results while running the same code.
A better practice is to always specify your time zone. If you want UTC/GMT, say so. If you want CET, say so. (Actually, don't use the three-letter code like CET as they are not standardized and have duplicates – use a time zone name such as Europe/Prague or Europe/Paris.) When parsing that string, specify the time zone to be incorporated within the new DateTime object.
Example Code
Here is some example code showing how to specify the time zone while parsing. Note the call to withZone().
Note that the result of all three parsings is the same moment in the time line of the Universe. To make that point, my code dumps to the console the milliseconds since the Unix Epoch backing each DateTime object. Usually I try to not use nor think about the milliseconds-since-epoch. But here the use of milliseconds-since-epoch proves a point.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
String dateString = "2013-11-20 18:20:00 +01:00";
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss Z");
// Time Zone list… http://joda-time.sourceforge.net/timezones.html (not quite up-to-date, read page for details)
DateTime dateTimeInUtc = formatter.withZone( DateTimeZone.UTC ).parseDateTime( dateString );
DateTime dateTimeInPrague = formatter.withZone( DateTimeZone.forID( "Europe/Prague" ) ).parseDateTime(dateString);
DateTime dateTimeInVancouver = formatter.withZone( DateTimeZone.forID( "America/Vancouver" ) ).parseDateTime(dateString);
Dump to console…
System.out.println( "dateTimeInUtc: " + dateTimeInUtc + " … In Milliseconds since Unix Epoch: " + dateTimeInUtc.getMillis() );
System.out.println( "dateTimeInPrague: " + dateTimeInPrague + " … In Milliseconds since Unix Epoch: " + dateTimeInPrague.getMillis() );
System.out.println( "dateTimeInVancouver: " + dateTimeInVancouver + " … In Milliseconds since Unix Epoch: " + dateTimeInVancouver.getMillis() );
When run… (Note that whether this code runs on your computer or mine, we both get the same results!)
dateTimeInUtc: 2013-11-20T17:20:00.000Z … In Milliseconds since Unix Epoch: 1384968000000
dateTimeInPrague: 2013-11-20T18:20:00.000+01:00 … In Milliseconds since Unix Epoch: 1384968000000
dateTimeInVancouver: 2013-11-20T09:20:00.000-08:00 … In Milliseconds since Unix Epoch: 1384968000000
Standard question: what time zone are you in? CET?
I assume the parsed DateTime is correct? What timezone does it have?
Bear in mind that Date doesn't have timezones. I'm not even sure if it actually considers Timezone.getDefault().
So, in short it looks like you have a timezone different from +1 and that's why your time is moved by one hour.
-- edit --
hold on. why do you even expect 19:20? The text says 18:20 +1, Joda parses this just like that and Date drops the timezone. That's it.

Categories

Resources