Re: NSTimestamp bug in timestampByAddingGregorianUnits
Re: NSTimestamp bug in timestampByAddingGregorianUnits
- Subject: Re: NSTimestamp bug in timestampByAddingGregorianUnits
- From: Timo Hoepfner <email@hidden>
- Date: Wed, 7 Oct 2009 22:28:46 +0200
I reported this one as bug #6299476 about a year ago (state is still
"Open"), might be the same problem:
17-Oct-2008 02:14 AM Timo Höpfner:
I have modelled calendar entries, which have a timestamp attribute.
I wanted to build a qualifier that matches all entries within a
month so I created start and end timestamps programatically.
The start timestamp is no problem. To get the end timestamp, I used
NSTimestamp.timestampByAddingGregorianUnits and added "a month minus
one second". This works fine for GMT, but gives me funky results for
e.g. Europe/Berlin. Please see code and output below.
Daylight Saving Time would explain one hour differences, but not
e.g. loosing two complete days for March 2008 Europe/Berlin.
When using a start date with time offset of 2 hours or more, the
problem goes away.
I think something like the following is happening:
-At some point timestampByAddingGregorianUnits needs to determine
the number of days of the month(s)
-To do so, it tries to determine the month of the timestamp the
method is called on
-While determining the month, it is using the wrong time zone (GMT?)
-As a result it uses the wrong month for timestamps where the month
differs in the two time zones involved.
public class NSTimestampTest {
public static void main(String[] args) {
int year = 2008;
// This one works
NSTimeZone gmt = NSTimeZone.getGMT();
test(gmt, year);
// This one doesn't
NSTimeZone berlin = NSTimeZone.timeZoneWithName("Europe/Berlin",
false);
test(berlin, year);
}
private static void test(NSTimeZone timezone, int year) {
NSTimestampFormatter formatter = new NSTimestampFormatter("%Y-%m-
%d %H:%M:%S %Z");
formatter.setDefaultFormatTimeZone(timezone);
for (int month = 1; month <= 12; month++) {
NSTimestamp start = new NSTimestamp(year, month, 1, 0, 0, 0,
timezone);
NSTimestamp end = start.timestampByAddingGregorianUnits(0, 1, 0,
0, 0, -1);
System.out.printf("%s -> %s\n", formatter.format(start),
formatter.format(end));
}
}
}
Output:
2008-01-01 00:00:00 Etc/GMT -> 2008-01-31 23:59:59 Etc/GMT
2008-02-01 00:00:00 Etc/GMT -> 2008-02-29 23:59:59 Etc/GMT
2008-03-01 00:00:00 Etc/GMT -> 2008-03-31 23:59:59 Etc/GMT
2008-04-01 00:00:00 Etc/GMT -> 2008-04-30 23:59:59 Etc/GMT
2008-05-01 00:00:00 Etc/GMT -> 2008-05-31 23:59:59 Etc/GMT
2008-06-01 00:00:00 Etc/GMT -> 2008-06-30 23:59:59 Etc/GMT
2008-07-01 00:00:00 Etc/GMT -> 2008-07-31 23:59:59 Etc/GMT
2008-08-01 00:00:00 Etc/GMT -> 2008-08-31 23:59:59 Etc/GMT
2008-09-01 00:00:00 Etc/GMT -> 2008-09-30 23:59:59 Etc/GMT
2008-10-01 00:00:00 Etc/GMT -> 2008-10-31 23:59:59 Etc/GMT
2008-11-01 00:00:00 Etc/GMT -> 2008-11-30 23:59:59 Etc/GMT
2008-12-01 00:00:00 Etc/GMT -> 2008-12-31 23:59:59 Etc/GMT
2008-01-01 00:00:00 Europe/Berlin -> 2008-01-31 23:59:59 Europe/Berlin
2008-02-01 00:00:00 Europe/Berlin -> 2008-02-29 23:59:59 Europe/Berlin
2008-03-01 00:00:00 Europe/Berlin -> 2008-03-29 23:59:59 Europe/Berlin
2008-04-01 00:00:00 Europe/Berlin -> 2008-04-30 23:59:59 Europe/Berlin
2008-05-01 00:00:00 Europe/Berlin -> 2008-05-30 23:59:59 Europe/Berlin
2008-06-01 00:00:00 Europe/Berlin -> 2008-06-30 23:59:59 Europe/Berlin
2008-07-01 00:00:00 Europe/Berlin -> 2008-07-30 23:59:59 Europe/Berlin
2008-08-01 00:00:00 Europe/Berlin -> 2008-08-31 23:59:59 Europe/Berlin
2008-09-01 00:00:00 Europe/Berlin -> 2008-09-30 23:59:59 Europe/Berlin
2008-10-01 00:00:00 Europe/Berlin -> 2008-10-30 22:59:59 Europe/Berlin
2008-11-01 00:00:00 Europe/Berlin -> 2008-11-30 23:59:59 Europe/Berlin
2008-12-01 00:00:00 Europe/Berlin -> 2008-12-30 23:59:59 Europe/Berlin
And while we're talking about date/time related bugs, I also filed
this one as #6494932 in January 2009 (also state "Open"):
14-Jan-2009 11:11 AM Timo Höpfner:
rawOffset of NSTimeZone is not set correctly. E.g. it reports zero
for Europe/Berlin while it should be one hour. When using
java.util.TimeZone instead of NSTimeZone, everything is OK.
This happens with both WO 5.3.3 and 5.4.3.
--- Reproduction code ---
package timo.tests;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import com.webobjects.foundation.NSTimeZone;
import com.webobjects.foundation.NSTimestamp;
public class Timezones {
public static void main(String[] args) {
test(TimeZone.getTimeZone("Europe/Berlin"));
test(NSTimeZone.timeZoneWithName("Europe/Berlin", false));
}
private static void test(TimeZone timeZone) {
System.out.println("Testing with " + timeZone.getClass() + " (" +
timeZone + ")\n");
System.out.println("timeZone.getRawOffset() = " +
timeZone.getRawOffset()+"\n");
Calendar calendar = new GregorianCalendar(timeZone);
Date trialTime = new NSTimestamp(2008, 5, 1, 0, 0, 0, timeZone);
System.out.println(trialTime);
calendar.setTime(trialTime);
System.out.println("YEAR: " + calendar.get(Calendar.YEAR));
System.out.println("MONTH+1: " + (calendar.get(Calendar.MONTH) +
1));
System.out.println("DAY_OF_MONTH: " + calendar.get
(Calendar.DAY_OF_MONTH));
System.out.println();
System.out.println("HOUR_OF_DAY: " + calendar.get
(Calendar.HOUR_OF_DAY));
System.out.println("MINUTE: " + calendar.get(Calendar.MINUTE));
System.out.println("SECOND: " + calendar.get(Calendar.SECOND));
System.out.println();
System.out.println("ZONE_OFFSET: " + calendar.get
(Calendar.ZONE_OFFSET));
System.out.println("DST_OFFSET: " + calendar.get
(Calendar.DST_OFFSET));
System.out.println("---");
}
}
--- Output ---
Testing with class sun.util.calendar.ZoneInfo
(sun.util.calendar.ZoneInfo[id="Europe/
Berlin
",offset
=
3600000
,dstSavings
=
3600000
,useDaylight=true,transitions=143,lastRule=java.util.SimpleTimeZone
[id=Europe/
Berlin
,offset
=
3600000
,dstSavings
=
3600000
,useDaylight
=
true
,startYear
=
0
,startMode
=
2
,startMonth
=
2
,startDay
=
-1
,startDayOfWeek
=
1
,startTime
=
3600000
,startTimeMode
=
2
,endMode
=
2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]])
timeZone.getRawOffset() = 3600000
2008-04-30 22:00:00 Etc/GMT
YEAR: 2008
MONTH+1: 5
DAY_OF_MONTH: 1
HOUR_OF_DAY: 0
MINUTE: 0
SECOND: 0
ZONE_OFFSET: 3600000
DST_OFFSET: 3600000
---
Testing with class com.webobjects.foundation.NSTimeZone (Europe/
Berlin (CET) offset 3600)
timeZone.getRawOffset() = 0
2008-04-30 22:00:00 Etc/GMT
YEAR: 2008
MONTH+1: 4
DAY_OF_MONTH: 30
HOUR_OF_DAY: 23
MINUTE: 0
SECOND: 0
ZONE_OFFSET: 0
DST_OFFSET: 3600000
---
Let's hope, that one day something like Star Trek's star dates will
replace our current date/time system...
Timo
Am 07.10.2009 um 22:13 schrieb Ramsey Gurley:
Hi all,
Executing the following code with a default time zone of US Eastern
time
NSTimestamp ts1 = new NSTimestamp
(2009,11,1,0,0,0,NSTimeZone.defaultTimeZone());
NSTimestamp ts2 = ts1.timestampByAddingGregorianUnits( 0, 0, 1, 0,
0, 0 );
NSTimestamp ts3 = new NSTimestamp
(2009,11,2,0,0,0,NSTimeZone.defaultTimeZone());
System.out.println(NSTimeZone.defaultTimeZone().getID());
System.out.println(ts1 + "\n" + ts2 + "\n" + ts3);
produces the following result :-/
America/New_York
2009-11-01 04:00:00 Etc/GMT
2009-11-02 04:00:00 Etc/GMT
2009-11-02 05:00:00 Etc/GMT
Is this a known bug?
Ramsey
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden