Calendar.setTimeInMillis error - why is that? [duplicate] - java

This question already has answers here:
Java: Date from unix timestamp
(11 answers)
Closed 3 years ago.
calendar gets wrong unix time as I got.
long millis = 1568814839L;
System.out.println(millis); //1568814839
Calendar.getInstance(TimeZone.getTimeZone("Asia/Tashkent"));
calendar.setTimeInMillis(millis);
System.out.println(calendar.get(Calendar.MILLISECOND));//839
What should I do? Calendar.YEAR should be 2019 with that millis. However, calendar gives me 1970, why?

The error is due to you confusing time in milliseconds and time in seconds. 1568814839L is the number of seconds since 1/1/1970, but you're treating it as milliseconds. This is quite easy to check:
long millis = 1568814839L;
System.out.println(millis); //1568814839
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Asia/Tashkent"));
System.out.println(calendar.getTimeInMillis()); //1568820981321
calendar.setTimeInMillis(millis);
System.out.println(calendar.get(Calendar.YEAR));//839
This will produce:
1568814839
1568820981321
1970
As you can see, your number is 3 orders of magnitude off. Add three 0's to the end of your millis number:
long millis = 1568814839000L;
...
System.out.println(calendar.get(Calendar.YEAR));
Now you get:
1568814839000
1568821211006
2019

java.time
The modern code would use java.time, the modern Java date and time API.
Feed your count of whole seconds since 1970-01-01T00:00Z to the Instant class:
ZonedDateTime zdt = Instant.ofEpochSecond(1_568_814_839L)
.atZone(ZoneId.of("Asia/Tashkent"));
System.out.println(zdt);
System.out.println("Year: " + zdt.getYear());
System.out.println("Millisecond of second: "
+ zdt.get(ChronoField.MILLI_OF_SECOND));
Output is:
2019-09-18T18:53:59+05:00[Asia/Tashkent]
Year: 2019
Millisecond of second: 0
As others have said, your number is seconds since the epoch, not milliseconds.
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern 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.
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.time to 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

Converted unix timestamp with a timezone addition in seconds gives a true local date time on Android emulator but not in real device?

I took a date from a web service in UNIX timestamp. I milltuplied it by 1000L then I added the timezone to it in seconds (also provided by the web service) milltiplied by 1000 to obtain the date according to the country in which the application will run and not the UTC date.
In the emulator the date time provided is correct but when I tested on a real device it provided me the time with 1 hour more which does not correspond to the local time. Where is the problem?
long numberOfsecondsRise = json.getJSONObject("city").getInt("timezone");
long res=(json.getJSONObject("city").getLong("sunrise")*1000L +numberOfsecondsRise*1000) ;
Date rise=new java.util.Date(res);
DateFormat dfa = DateFormat.getTimeInstance();
sunFiled.setText(getResources().getString(R.string.sunrise)+": " + dfa.format(rise));
java.time and ThreeTenABP
Consider using java.time, the modern Java date and time API, for your time work. If for minSDK below API level 26, then through the backport, I will get back to that. First the code:
DateTimeFormatter timeFormatter
= DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
long sunriseUnixTs = 1_589_581_234;
ZonedDateTime sunriseApplicationTz = Instant.ofEpochSecond(sunriseUnixTs)
.atZone(ZoneId.systemDefault());
System.out.println("Sunrise: " + sunriseApplicationTz.format(timeFormatter));
Output from this example snippet in my time zone and locale:
Sunrise: 03.50.34
One of the things I find great about java.time is that the code makes it explicit that we are getting the time in the default time zone of the JVM where the application is running.
What went wrong in your code?
Adding the time zone offset of the city you are inquiring about is wrong. A Unix timestamp is independent of time zone. So if you multiply by 1000 and feed to new Date(long), you are getting a Date that holds the correct point in time. If you add a non-zero offset, you are getting a wrong point in time. Your emulator gave you the expected result, why, then? It might be because the offset from JSON was 0 (zero) or because the error was balanced out by the emulator using a different default time zone from what you had expected.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern 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.
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.time to 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.
A question about an Android emulator that seems to be using UTC as its default time zone rather than the time zone of the host operating system: Emulated Android Device shows wrong date (Windows 10)
Date (long date) constructor documentation says:
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.
This means the value is supposed to be in UTC. The time offset in seconds must be applied when formatting the date for display.
long numberOfsecondsRise = json.getJSONObject("city").getInt("timezone");
Date rise = new java.util.Date(json.getJSONObject("city").getLong("sunrise") * 1000L);
int offsetMinutes = numberOfsecondsRise / 60;
String sign = (offsetMinutes < 0 ? "-" : "+");
offsetMinutes = Math.abs(offsetMinutes);
String timeZoneID = String.format("GMT%s%d:%02d", sign, offsetMinutes / 60, offsetMinutes % 60);
DateFormat dfa = DateFormat.getTimeInstance();
dfa.setTimeZone(TimeZone.getTimeZone(timeZoneID));
sunFiled.setText(getResources().getString(R.string.sunrise) + ": " + dfa.format(rise));

How to get time entered by user in EditText and deduct 5 hrs 30 minutes from it?

I had two edit text for user to enter time (24 hours format).
How could i get those times from Edittext and deduct 5 hours and 30 minutes from user selected time.
Reason for deducting time : Converting IST to UTC timezone.
My final output should be like - HH:MM:SS:Milleseconds (Ex : 18:25:30:245635).
Thanks in advance.
java.time
ZoneId zone = ZoneId.of("Asia/Kolkata");
String timeString = "18:25:30.245635";
LocalTime time = LocalTime.parse(timeString);
LocalTime utcTime = LocalDate.now(zone) // Today
.atTime(time) // Today at the time in question
.atZone(zone) // Date and time in IST
.toOffsetDateTime() // Convert to OffsetDateTime for the next step
.withOffsetSameInstant(ZoneOffset.UTC) // Convert to UTC
.toLocalTime(); // Extract only the time of day
System.out.println("UTC time: " + utcTime);
Output is:
UTC time: 12:55:30.245635
I have assumed today’s date. Please check if this assumption is right for you. While the UTC offset for Asia/Kolkata hasn’t changed much recently, other time zones change their offset twice a year.
I changed your time format to have a period (point) rather than a colon between the seconds and fraction of second as is customary. If you do require a colon there, you need a DateTimeFormatter for parsing.
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern 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.
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.time to 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.
Wikipedia article: ISO 8601

How to get the ending date if ending time is not lies in current date in android

I am trying to make an application which takes start date, start time and end time. If the end time does not lie in the start date then how I can calculate the ending date based on the end time.
Here is the screenshot of what I want
As you can see in the picture when you enter start date, start time and end time, the end time is ending on the next date, it is automatically calculating the end date. (I also underlined it.)
How I can achieve this things? What the logic behind.
java.time
ZoneId zone = ZoneId.of("America/Chicago");
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("h:mm a (OOOO)", Locale.US);
LocalDate startDate = LocalDate.of(2019, Month.SEPTEMBER, 18);
LocalTime startTime = LocalTime.of(14, 0);
LocalTime endTime = LocalTime.of(4, 0);
ZonedDateTime start = ZonedDateTime.of(startDate, startTime, zone);
ZonedDateTime end = ZonedDateTime.of(startDate, endTime, zone);
if (end.isBefore(start)) {
end = ZonedDateTime.of(startDate.plusDays(1), endTime, zone);
}
System.out.println("Date: " + startDate);
System.out.println("Start Time: " + start.format(timeFormatter));
System.out.println("End Time: " + end.format(timeFormatter));
System.out.println("Ends on " + end.toLocalDate());
Output from this snippet is:
Date: 2019-09-18
Start Time: 2:00 PM (GMT-05:00)
End Time: 4:00 AM (GMT-05:00)
Ends on 2019-09-19
I have shown you how to use a DateTimeFormatter for formatting the times. You will probably want to use formatters for the dates too.
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern 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.
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.time to 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.

Convert "using excel method" numeric value in date - java

I have an integer that when I put on Google Sheets, it represents the date 14/10/1911 (integer value is 4305).
I need to do this same conversion in my code using Java. So I'll have an array of integer that goes down by a factor of 1 (like 4305, 4304, 4303...) and I need to convert these integers into date (14/10/1911, 13/10/1911, 12/10/1911...) using the same method that excel/sheets uses.
Any ideas?
Thanks
LocalDate msBaseDate = LocalDate.of(1899, Month.DECEMBER, 30);
int[] integers = { 4305, 4304, 4303 };
for (int integerValue : integers) {
LocalDate date = msBaseDate.plusDays(integerValue);
System.out.println(date);
}
Output from this snippet is:
1911-10-14
1911-10-13
1911-10-12
Excel and other Microsoft products and possibly other software too use December 30, 1899, as a base date and represent dates as a count of days since that date. So just add the number to that date. I am using LocalDate from java.time, the modern Java date and time API.
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern 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.
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.time to 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.

DateTime("2019-02-16T10:00:00+08:00") conversion to local date time with offset value

I get the datetime content in the below string format with offset time value from the source system.
2019-02-16T10:00:00+08:00
Where i want to convert that into local date time using the offset value.I tried the below, but not getting the expected result.
DateTime date = new DateTime("2019-02-16T10:00:00+08:00");
-->output == 2019-02-16T02:00:00.000Z (the hour is decreased instead of increasing)
DateTime date = new DateTime("2019-02-16T10:00:00-08:00");
-->output == 2019-02-16T18:00:00.000Z (the hour is increased instead of decreasing).
is there any simple way to the expected output?
Note: I am using Java 1.7
What you are doing is correct. To get the time in your local time zone:
DateTime date = new DateTime("2019-02-16T10:00:00+08:00");
DateTime dateTimeInLocalTimeZone = date.withZone(DateTimeZone.getDefault());
System.out.println(dateTimeInLocalTimeZone);
On my computer in Europe/Copenhagen time zone I got
2019-02-16T03:00:00.000+01:00
As has been said in the comments, +08:00 is the offset that has already been added compared to UTC time. So your string denoted the same point in time as 2019-02-16T02:00:00+00:00. It may also be written as 2019-02-16T02:00:00Z since Z (pronounced “Zulu”) means UTC.
java.time and ThreeTen Backport
If you are not already tied to Joda-Time, you may prefer to use java.time, the modern Java date and time API. The code is similar:
OffsetDateTime sourceDateTime = OffsetDateTime.parse("2019-02-16T10:00:00+08:00");
ZonedDateTime dateTimeInLocalTimeZone = sourceDateTime.atZoneSameInstant(ZoneId.systemDefault());
2019-02-16T03:00+01:00[Europe/Copenhagen]
Question: Can I use java.time on Java 1.7?
Note: I am using Java 1.7
No big problem, java.time just requires at least Java 6. I have run the above code on jdk1.7.0_79.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern 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.
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.time to 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.
Another way to do that :
String dt = "2019-02-16T10:00:00+08:00";
ZonedDateTime zd = ZonedDateTime.parse("2019-02-16T10:00:00+08:00");
System.out.println(zd.toLocalDateTime().plusSeconds(zd.getOffset().getTotalSeconds()));
Output
2019-02-16T18:00

Categories

Resources