Since some game designs can use a date that was in the past or in the future, and in any time zone of emulating the time of a date, even we never reach them in reality. For this assumption, not to mention the fact that I am counting on fake date time s, but for the correctness of the calculation at any time in any time zone, as it actually was.
Earlier I asked a question about the time zone of China in Java, which was seen as a duplicate question, and I deleted it like that. However, from this stream of comments , I know that this is some kind of time rewind problem (transition?) In Java, and not just a change in time zone.
And now I re-posted this question in a different way to present this problem as follows:
Java code
import org.joda.time.*; import java.util.*; class PandaTest { static long Subtract( Date minuend, Date subtrahend, DateTimeZone zone) { long millis; if(null==zone) millis=minuend.getTime()-subtrahend.getTime(); else { long rhs= (new LocalDateTime(subtrahend)).toDateTime(zone) .getMillis(); long lhs= (new LocalDateTime(minuend)).toDateTime(zone) .getMillis(); millis=lhs-rhs; } return millis/1000; } static Date MakeTime( int year, int month, int day, int hour, int minute, int second ) { Calendar calendar= Calendar.getInstance(TimeZone.getTimeZone("PRC")); calendar.set(year, month-1, day, hour, minute, second); return calendar.getTime(); } static void puts(String arg0) { System.out.println(arg0); } static void ShowDuration(DateTimeZone zone, Date ... args) { int argc=args.length; puts("--- "); puts("Time Zone: "+(null!=zone?zone.toString():"unspecified")); for(int i=0; argc-->0; ++i) { puts("Time "+i+": "+args[i]); if(i>0) { long duration=Subtract(args[i], args[i-1], zone); puts("Duration = "+duration); } } } public static void main(String[] args) { Date retainsOfTheDay=MakeTime(1900, 1, 1, 8, 5, 51+0); Date somewhereInTime=MakeTime(1900, 1, 1, 8, 5, 51+1); DateTimeZone zone=DateTimeZone.forID("PRC"); ShowDuration(null, retainsOfTheDay, somewhereInTime); ShowDuration(zone, retainsOfTheDay, somewhereInTime); } }
The problem arises if I built a LocalDateTime JodaTime from Date Java. The JDK version is 7u17 and the JodaTime is 2.2. This does not happen in C # with NodaTime, I put an alternate version of the code at the end of this post for contrast.
Question
How does the transition happen, is it accurate as the Unix era?
I may be misusing the term transition. I mean the strange result of subtracting 1900/1/1 8:5:52 at 1900/1/1 8:5:51 in Java. There was no change in time zone at that time.
Does something like this happen only in a specific time zone or in all time zones (perhaps at some other point in time)?
If one could count on an arbitrary date time in any time zone, expecting that the result will always be correct, should Date and Calendar be used?
If so, how to use them without causing a problem?
Should we no longer use Date and Calender in Java, as soon as we can count on date time before 1970 or after 2038?
Alternative code
The code contains content in both C # and Java, which allows you to compare the result with C # and Java:
// Like Java, like Sharp ... the code contains content either in Java or C# // An odd number of `slash-star-slash` at the beginning to compile in Java // An even number of `slash-star-slash` at the beginning to compile in C# // ps: zero would be treated as an even number using Date=System.DateTime; using NodaTime.TimeZones; using NodaTime; using System.Collections.Generic; using System.Linq; using System; /*/ import org.joda.time.*; import java.util.*; // ClockCant in Java class ClockCant { public static Date MakeTime( int year, int month, int day, int hour, int minute, int second ) { Calendar calendar= Calendar.getInstance(TimeZone.getTimeZone("PRC")); calendar.set(year, month-1, day, hour, minute, second); return calendar.getTime(); } public static DateTimeZone GetZoneFromId(String id) { return DateTimeZone.forID(id); } public static String GetYourZoneId() { return DateTimeZone.getDefault().getID(); } public static long Subtract( Date minuend, Date subtrahend, DateTimeZone zone) { long millis; if(null==zone) millis=minuend.getTime()-subtrahend.getTime(); else { long rhs= (new LocalDateTime(subtrahend)).toDateTime(zone) .getMillis(); long lhs= (new LocalDateTime(minuend)).toDateTime(zone) .getMillis(); millis=lhs-rhs; } return millis/1000; } } // a minimum implementation of C#-like List<T> for Java class List<T> { public T[] ToArray() { return _items; } public int Count() { return _items.length; } public List(T ... args) { _items=args; } T[] _items; } /*/// ClockCant in C# class ClockCant { public static Date MakeTime( int year, int month, int day, int hour, int minute, int second) { return new Date(year, month, day, hour, minute, second); } public static DateTimeZone GetZoneFromId(String id) { return DateTimeZoneProviders.Tzdb[id]; } public static String GetYourZoneId() { return DateTimeZoneProviders.Tzdb.GetSystemDefault().Id; } public static long Subtract( Date minuend, Date subtrahend, DateTimeZone zone) { long ticks; if(null==zone) ticks=minuend.Subtract(subtrahend).Ticks; else { var rhs= LocalDateTime.FromDateTime(subtrahend) .InZoneLeniently(zone); var lhs= LocalDateTime.FromDateTime(minuend) .InZoneLeniently(zone); ticks=(lhs.ToInstant()-rhs.ToInstant()).Ticks; } return ticks/TimeSpan.TicksPerSecond; } } // extension for Java-like methods in C# static partial class JavaExtensions { public static String toString(this Object x) { return x.ToString(); } } class PandaTest { /*/ class PandaTest { // in Java public static void main(String[] args) { Language="Java"; Main(args); } static void puts(String arg0) { System.out.println(arg0); } static void ShowDuration(DateTimeZone zone, Date ... args) { ShowDuration(zone, new List<Date>(args)); } /*/// in C# static void puts(String arg0) { Console.WriteLine(arg0); } static void ShowDuration(DateTimeZone zone, params Date[] args) { ShowDuration(zone, args.ToList()); } /**/// the following code are for both C# and Java static void ShowDuration(DateTimeZone zone, List<Date> args) { int argc=args.Count(); Date[] argv=args.ToArray(); puts("--- "); puts("Time Zone: "+(null!=zone?zone.toString():"unspecified")); for(int i=0; argc-->0; ++i) { puts("Time "+i+": "+argv[i]); if(i>0) { long duration=ClockCant.Subtract(argv[i], argv[i-1], zone); puts("Duration = "+duration); } } } static void Main(String[] args) { Date retainsOfTheDay=ClockCant.MakeTime(1900, 1, 1, 8, 5, 51+0); Date somewhereInTime=ClockCant.MakeTime(1900, 1, 1, 8, 5, 51+1); DateTimeZone zone=ClockCant.GetZoneFromId("PRC"); puts("Current Time Zone: "+ClockCant.GetYourZoneId()); puts("Language: "+Language); ShowDuration(null, retainsOfTheDay, somewhereInTime); ShowDuration(zone, retainsOfTheDay, somewhereInTime); } static String Language="C#"; }
To compile in Java, add /*/ at the beginning of the code as follows: