How do I convert milliseconds to days, hour, minutes - date

I tried to do this:
long Plptime = player.getStatistic(Statistic.PLAY_ONE_TICK)*50L; //from ticks to ms(1 tick (20 each sec) by 50 gives aprox the ms)
SimpleDateFormat formatter = new SimpleDateFormat("dd 'days,' HH
'hours and' mm 'minutes'", Locale.getDefault());
Date date = new Date(Plptime);
String result1 = formatter.format(date);
But when it messages the String to the player (minecraft by the way), the hours and days start on 1 while the min start on 0, for example right when someone just joins his playtime will be 01days 01 hours 00 min. Any solutions? Thanks

Java 9 or later
Let’s first declare a couple of helpful constants.
private static final int TICKS_PER_SECOND = 20;
public static final Duration ONE_TICK = Duration.ofSeconds(1).dividedBy(TICKS_PER_SECOND);
Now do:
int ticks = player.getStatistic(Statistic.PLAY_ONE_TICK);
Duration plpTime = ONE_TICK.multipliedBy(ticks);
String result1 = String.format(Locale.ENGLISH, "%02d days %02d hours and %02d minutes",
plpTime.toDays(), plpTime.toHoursPart(), plpTime.toMinutesPart());
System.out.println(result1);
This prints a string like
00 days 17 hours and 08 minutes
Possibly the number of ticks per second (20) is already declared as a constant somewhere in Bukkit, I don’t know. If it is, take that one rather declaring your own.
Java 6, 7 or 8
The toXxxPart methods I used were introduced in Java 9. Without them we need to calculate the individual parts like this:
long days = plpTime.toDays();
plpTime = plpTime.minusDays(days);
long hours = plpTime.toHours();
plpTime = plpTime.minusHours(hours);
long minutes = plpTime.toMinutes();
String result1 = String.format(Locale.ENGLISH, "%02d days %02d hours and %02d minutes",
days, hours, minutes);
The result is the same as above.
Question: How can that work in Java 6 or 7?
The Duration class that I am using is part of java.time, the modern Java date and time API
In Java 8 and later and on newer Android devices (from API level 26, I’m told) java.time comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
What went wrong in your code?
Why the hours seem to start at 1 (not 0): It’s your time zone. When you create a Date from your milliseconds, you get the point in time that many milliseconds after the epoch defined as 00:00 UTC on Jan 1, 1970 (which conceptually is quite misleading when the question was when a player joined). If your time zone was 1 hour ahead of UTC in the winter of 1970 (like Central European time, for example), it was already 1 o’clock at the epoch, so the hours count from there.
And since it was January 1, the day is given as 1, of course. Curiously, if you had been in a time zone west of GMT (America/Los_Angeles to give just one example), the date would still have been December 31, 1969 in the first hours after the epoch, so the newly joined player might appear to have been there for 31 days, 16 hours and 00 minutes, for example.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.timeto Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.

Related

Why is the time before 1892 printed incorrectly in Swift?

I came across a weird date behaviour in Swift.
If I try to print any date before 1891, the minutes and seconds will be printed incorrectly with offset by 2 minutes and 16 seconds like this:
Code Sample:
// incorrectly printed date
let year1981 = Calendar.current.date(from: .init(year: 1891, hour: 9))
print(year1981!) // will print 1891-01-01 08:02:16 +0000
// correctly printed date
let year1982 = Calendar.current.date(from: .init(year: 1892, hour: 9))
print(year1982!) // will print 1892-01-01 08:00:00 +0000
Is there any rational reason for this behaviour or it is a bug? Thanks for any reply!
Tested in Xcode Playground 14.1
Based on the comments you are in the "Europe/Prague" timezone.
According to this website information:
When local standard time was about to reach
Thursday, October 1, 1891, 12:00:00 midnight clocks were turned forward 0:02:16 hours to
Thursday, October 1, 1891, 12:02:16 am local standard time instead.
This change would explain the results you are seeing when converting such a date.
So it is not a bug. It's just one of many examples of how complicated Date and Calendar code is due to all of the obscure details of time zones and day light saving time can be.

millisecondSinceEpoch returning weird value when parsing date around 1969

I don't know if this is a bug or if I'm using this method incorrectly.
Can someone explain to me why I got a weird value when parsing this date?
This is the minimal script:
void main(){
DateTime zero = DateTime.fromMillisecondsSinceEpoch(0);
print(zero.millisecondsSinceEpoch);
DateTime errorDate2 = DateTime(1969,1,1);
print(errorDate2.millisecondsSinceEpoch);
DateTime errorDate = DateTime(1969,10,2);
print(errorDate.millisecondsSinceEpoch);
}
Based on my sample, the result seems fine when I parse dates bigger than 0 milliseconds since the epoch.
But it gets weird when I parse some date less than 0 milliseconds since the epoch.
From that script, I got this output
0
-31536000000
-7862400000
I parse that output to this website.
In the first and second results, the results are fine, but in the third result, I got a date around 1720.
Can someone explain to me what happens to that function? Did I use it wrong?
What should I do when I want to parse a date less than 0 milliseconds since the epoch?
In a computing context, an epoch is the date and time relative to which a computer's clock and timestamp values are determined. The epoch traditionally corresponds to 0 hours, 0 minutes, and 0 seconds (00:00:00) Coordinated Universal Time (UTC) on a specific date, which varies from system to system. Most versions of Unix, for example, use January 1, 1970 as the epoch date; Windows uses January 1, 1601; Macintosh systems use January 1, 1904, and Digital Equipment Corporation's Virtual Memory System (VMS) uses November 17, 1858.
So here epoch time starts on January 1, 1970, so it will give you a minus value for milliseconds.
You can still parse the date. it will gave just minus value nothing else.
void main() {
DateTime zero = DateTime.fromMillisecondsSinceEpoch(0);
print(zero.millisecondsSinceEpoch);
DateTime errorDate2 = DateTime(1969,1,1);
print(errorDate2.millisecondsSinceEpoch);
DateTime errorDate = DateTime(1969,10,2);
print(errorDate.millisecondsSinceEpoch);
DateTime error3 = DateTime.fromMillisecondsSinceEpoch(errorDate.millisecondsSinceEpoch);
print(error3);
}
Result is
0
-31555800000
-7882200000
1969-10-02 00:00:00.000
It seems that the bug comes from the website that I refer to it.
Thanks! #jamesdlin

Windows 8 RT DateTime.FromOADate

Recently started porting an application from Windows Phone 8 to Windows 8 RT, and faced strange problem: can't find a way to convert DateTime structure to double OLE date.
Earlier, there were methods DateTime.FromOADate and DateTime.ToOADate to do this, but now they are not available.
...
double oaNow = System.DateTime.Now.ToOADate(); //ToOADate undefined
...
What can be wrong?
For whatever reason this was not included in the RT targets. It doesn't do anything particularly special, it it appears it could be portable.
You can probably duplicate the functionality in your own method by looking at the Reference source for the .NET Framework.
Try
double oaNow = System.DateTime.Now.Subtract(new DateTime(1899, 12, 30)).TotalDays;
According to the documentation
An OLE Automation date is implemented as a floating-point number whose integral component is the number of days before or after midnight, 30 December 1899, and whose fractional component represents the time on that day divided by 24. For example, midnight, 31 December 1899 is represented by 1.0; 6 A.M., 1 January 1900 is represented by 2.25; midnight, 29 December 1899 is represented by -1.0; and 6 A.M., 29 December 1899 is represented by -1.25.

iPhone Datepicker.date is 4 hours and 56 minutes fast, help?

Hey all so as the title suggest I just have a date picker and it appears to be 4 hours and 56 minutes fast.. which is very strange. Code is very straight foreword:
NSLog(#"%#",datePicker.date);
In the view did load
datePicker.timeZone = [NSTimeZone localTimeZone];
Any ideas/suggestions?
ETA: for example if I set the time as 4 00 PM I get this in the NSLog
0001-01-01 20:56:02 +0000
Set minimumDate and maximumDate on your date picker to something sane.
Dates before October 1582 tend to have numerous issues in iOS, due to some things recognizing the Julian/Gregorian calendar transition and other things not. There also seems to be accuracy issues in the times when you deal NSDates near the year 1.

Is there a class in JDK to represent an hour of the day, but not necessarily a specific hour at a specific date?

Is there a class in JDK or Guava to represent an hour of the day, but not necessarily a specific hour at a specific date?
If not, why?
In JDK 1.3-1.7, the answer is no. A specific time within a day is much easier to calculate then date, because you don't have to deal with leap year, leap month, such headache stuff. A simple integer is just enough. When you need to convert the time to a locale string, using SimpleDateFormatter or whatever, you can simply convert the time to a Date, just ignore the date part:
int time = 8 * 60 + 34; // 8:34 am
Date date = new Date(60000L * time);
Reset the time zone to +0, and pass the date to the formatter:
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT+0"));
sdf.format(date);
You could simply wrap a byte into a class and every time that the current hour passes 23 within your increment() (or appropriate name) method, set the value of the byte to 0, and whenever the value passes below 0 in your decrement() (or appropriate name) method, set the value of the byte to 23.
As far as I know, there is not a specific class representing Hour (in the JDK or Guava), but there are easy to use classes to fetch the hours from a specific instance of time (which is what I am assuming you are after with this question).
You could use JODA-Time, as Paŭlo Ebermann mentions, but that is an external library. Within the JDK, there is a class called Calendar, which has many useful methods.
To get the hour of a long representing the current time, you could do this:
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis());
int hour = c.get(Calendar.HOUR); //returns 0-11
int hourOfDay = c.get(Calendar.HOUR_OF_DAY); //returns 0-23