Simple Date format gives wrong info from epoch timestamp - android

I found that this gives a wrong date. but how i can not solve it. please someone help me.
I am new in android Development.
Thanks in advance;
String timestamp = "1538970640";
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM 'at' hh:mm a z" );
String dateString = formatter.format(new Date(Long.parseLong(timestamp)));
This returns:
19 Jan at 01:29 AM GMT+06:oo
But it should be:
8 Oct at 9:50 AM GMT+06:00

The java.util.Date constructor accepts milliseconds since the Epoch, not seconds:
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.
The following code which uses ms is working:
String timestamp = "1538970640000"; // use ms NOT s
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM 'at' hh:mm a z" );
String dateString = formatter.format(new Date(Long.parseLong(timestamp)));
08 Oct at 05:50 AM CEST
Demo
Part of the problem you were facing is that your date format omitted the year component, which was actually coming up as 1970.

java.time and ThreeTenABP
I recommend you use java.time, the modern Java date and time API, for your date and time work.
DateTimeFormatter timestampFormatter = new DateTimeFormatterBuilder()
.appendValue(ChronoField.INSTANT_SECONDS)
.toFormatter();
DateTimeFormatter targetFormatter
= DateTimeFormatter.ofPattern("d MMM 'at' h:mm a z", Locale.ENGLISH);
String timestamp = "1538970640";
ZonedDateTime dateTime = timestampFormatter.parse(timestamp, Instant.FROM)
.atZone(ZoneId.systemDefault());
String dateString = dateTime.format(targetFormatter);
System.out.println(dateString);
Output is (when time zone is set to GMT+06:00, which by the way is not a true time zone):
8 Oct at 9:50 AM GMT+06:00
I am not very happy about converting date and time from one string format to another, though. In your app you should not handle date and time as strings but as proper date and time objects, for example Instant or ZonedDateTime. When you get a string from somewhere (a server?), parse it into a date-time object first thing. Only when you need to give string output, for example to the user, format your date and time into a string in the user’s time zone.
That said, java.time performs your conversion with just two formatters. No need to parse into a low-level long first.
Two more points:
Give your output formatter a locale to control the language used. Since AM and PM are hardly used in other languages than English, I figured that Locale.ENGLISH might be appropriate. You decide.
Since you want 8 Oct at 9:50 AM GMT+06:00, use just one d for day of month and one h for clock hour. Two digits will still be printed if the numbers go over 9, for example 10 Oct at 11:50 AM GMT+06:00.
What went wrong in your code?
Your number, 1538970640 (10 digits), denotes seconds since the epoch. This is the classical definition of a Unix timestamp. The Date constructor that you used expects milliseconds since the epoch. This is typical for the outdated Java date and time classes and methods. These years milliseconds since the epoch are typically 13 digits. As you can see, the modern Java date and time classes have better support for seconds here.
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 this case, instead of the constant Instant.FROM use the method references Instant::from.
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.

Related

Can't convert from local date to London date object

Android Studio 4.0, Java 6.
My GMT is GMT + 03:00
defaultConfig {
minSdkVersion 17
targetSdkVersion 28
const val LONDON_TIME_ZONE_ID = "Europe/London"
const val DEFAULT_DATE_JSON_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.000'Z'"
fun fromDateToLondonDate(localDate : Date) : Date? {
val dateLondonAsString = fromDate2LondonDateAsString(localDate)
val timeZoneLondon : TimeZone = TimeZone.getTimeZone(LONDON_TIME_ZONE_ID)
val dateLondon = getDateFromString(dateLondonAsString, timeZoneLondon)
if (BuildConfig.DEBUG)
Log.d("", "fromDateToLondonDate:" +
"\nlocalDate = $localDate"+
"\ndateLondonAsString = $dateLondonAsString"+
"\ndateLondon = $dateLondon")
return dateLondon
}
fun fromDate2LondonDateAsString(date : Date) : String? {
val timeZoneLondon : TimeZone = TimeZone.getTimeZone(LONDON_TIME_ZONE_ID)
val formatter: DateFormat = SimpleDateFormat(DEFAULT_DATE_JSON_FORMAT)
formatter.setTimeZone(timeZoneLondon)
val dateAsString : String = formatter.format(date)
return dateAsString
}
fun getDateFromString(str: String?, tz: TimeZone?): Date? {
return try {
val sdf = SimpleDateFormat(DEFAULT_DATE_JSON_FORMAT);
sdf.setTimeZone(tz)
val date = sdf.parse(str)
return date
} catch (e: ParseException) {
//e.printStackTrace();
null
}
}
and here result:
fromDateToLondonDate:
localDate = Tue Jun 16 13:14:59 GMT+03:00 2020
dateLondonAsString = 2020-06-16T11:14:59.000Z
dateLondon = Tue Jun 16 13:14:59 GMT+03:00 2020
as you can see the local date is Tue Jun 16 13:14:59 GMT+03:00 2020
and success convert to London date as String -> dateLondonAsString = 2020-06-16T11:14:59.000Z
Nice.
But I need to convert String to London Date. And I use method getDateFromString and result is not correct:
dateLondon = Tue Jun 16 13:14:59 GMT+03:00 2020
The correct London Date must be : Tue Jun 16 11:14:59 GMT+03:00 2020
Why getDateFromString not correct convert from string to date?
java.time and ThreeTenABP
To get a date-time object with a specific time zone turn to java.time, the modern Java date and time API. I am writing Java code, it’s what I can, and I trust you to translate:
ZoneId london = ZoneId.of("Europe/London");
Date date = getOldfashionedDateFromSomewhere();
System.out.println("Original Date: " + date);
ZonedDateTime dateTimeLondon = date.toInstant().atZone(london);
System.out.println("Date-time in London: " + dateTimeLondon);
Example output:
Original Date: Tue Jun 16 13:14:59 GMT+03:00 2020
Date-time in London: 2020-06-16T11:14:59+01:00[Europe/London]
A Date hasn’t got, as in cannot have a time zone. Yes, I know, when you print it, thereby implicitly calling its toString method, it prints a time zone. What happens is that it grabs the default time zone of your JVM and uses it for rendering the string. So as long as your JVM’s time zone setting is GMT+03:00, all of your Date objects will always print this time zone.
So if (in some another project) I need date with time zone
the better way is use java.time.ZonedDateTime (java 8) ?
It's at least the way I would recommend. As I said, using Date is not a way. Some ways are:
The poor and old-fashioned way: using GregorianCalendar.
The better way: using DateTime from Joda-Time. If accepting an external dependency, I'd prefer ThreeTenABP, though.
The good way: ZonedDateTime from java.time.
The advanced way: using Time4J. I haven't got experience, so I'd rather not recommend for or against. If your project has requirements that go beyond what java.time offers, I'd certainly research this option.
What went wrong in your code
First, you should probably not set your time zone to GMT+03:00. While your time zone uses this GMT offset now, that doesn’t mean that it always has nor that it always will. For correct results for historic and future dates use a real time zone ID such as Africa/Nairobi or Europe/Moscow, that is, in the region/city format. Just as you used Europe/London for British time (fortunately not GMT+00:00).
I have already mentioned the second point: You cannot use a Date for a date and time with a time zone because a Date hasn’t got a time zone. A Date is a point in time, no more, no less.
Next, 2020-06-16T11:14:59.000Z is wrong for the time in London. 11:14:59 is correct for the time of day. Z means UTC or offset 0 from UTC and is wrong since Great Britain uses summer time (DST) and hence is at offset +01:00 in June (as the output from my code above also says). The time at offset Z would have been 10:14:59. In other words, your time is 1 hour off. This definition of Z is part of the ISO 8601 standard. Your JSON format is ISO 8601 format. I include a link at the bottom. Since Z is an offset, you should always format and parse it as such and never hardcode it as a literal in your format pattern string.
Your conversion back from string to Date exhibits the same error, so it balances out with the error in converting to a String, and you succeed in getting an equivalent Date object back.
It's old Android project. And I can't use java.time. I can use only java.util.Date
You can certainly use java.time in old Android projects for old Android versions too.
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.
Wikipedia article: ISO 8601
All about java.util.Date on Jon Skeet’s coding blog
A related question about getting a Date with a time zone: TimeZone problem in Java
Joda-Time
Time4J - Advanced Date, Time, Zone and Interval Library for Java

Displaying the same date over DatePicker, ignoring device's TimeZone

I am displaying a date. The date varies with the Timezone of the device change. For example - Jan 01, 1960 for Timezone GMT +5.30 converts into Dec 31, 1959 for Timezone GMT -5.00. My requirement is that the date should be the same with any Timezone. I have converted my Date to UTC Date but still the date is changing according to Timezone. I have tried with few code as follows-
//Convering given date to UTC date using SimpleDateFormat
try {
final DateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
final Date date = sdf.parse(givenDate + "");
datePicker.setDate(date);
} catch (ParseException exception) {
exception.printStackTrace();
}
or
// Converting given date into GMT date using Timezone defference
final TimeZone tzLocal = TimeZone.getDefault();
final long gmtMillis = givenDate.getTime() - (tzLocal.getRawOffset());
final Date date = new Date();
date.setTime(gmtMillis);
datePicker.setDate(date);
I am using a custom DatePicker that has setDate(date) method (not android.widget.DatePicker).
I already have checked many similar Q&A but no luck. Thankyou
Not possible with java.util.Date
With java.util.Date you can’t. Despite the class name a Date does not represent a date. It is a point in time. So when the JVM’s default time zone may have changed since the Date was created, there is no way to detect which time zone was used when the Date was created. You can try all possible time zones, of course. This will typically give you two, occasionally three possible dates. Because it is never the same date in all time zones.
It may not be so bad as it sounds since the Date class is poorly designed and long outdated, so you shouldn’t use it anymore anyway.
Solution: java.time and ThreeTenABP
java.time, the modern Java date and time API, offers the LocalDate class. A LocalDate is a date without time of day and without time zone. So when you create a LocalDate worth Jan 01, 1960, it will always unambiguously be Jan 01, 1960.
LocalDate date = LocalDate.of(1960, Month.JANUARY, 1);
System.out.println(date);
There is nothing mysterious about the output:
1960-01-01
So the first suggestion is to base your custom DatePicker class on LocalDate rather than Date.
If you cannot afford to make that change right now, the short-term solution is to convert just before calling setDate (so only after the last change of default time zone has happened):
Instant startOfDayInDefaultZone = date.atStartOfDay(ZoneId.systemDefault())
.toInstant();
Date oldFashionedDate = DateTimeUtils.toDate(startOfDayInDefaultZone);
System.out.println(oldFashionedDate);
Output in my time zone was:
Fri Jan 01 00:00:00 CET 1960
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.
In the above code I am using the DateTimeUtils from the backport for converting from Instant to Date. If your Android version has java.time built in, instead use Date.from(startOfDayInDefaultZone) for this conversion.
Links
All about java.util.Date
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.

How to set the timezone for a SimpleDateFormat in Android Unit test

I want to test a method in a Date utility class that gets a Date from a String. The String that is passed is 1980-03-26T00:00:00.000+0200 and I want to compare the resulting date with assertEquals. The test failed with this output:
org.junit.ComparisonFailure:
Expected :Wed Mar 26 00:00:00 PST 1980
Actual :Wed Mar 26 00:00:00 SGT 1980
Here's my test:
INITIAL_DATA_DATE_FROM_STRING = "1980-03-26T00:00:00.000+0200";
EXPECTED_DATA_DATE_FROM_STRING = "Wed Mar 26 00:00:00 PST 1980";
// inside the method ...
date = DateUtils.getDateFromString(INITIAL_DATA_DATE_FROM_STRING);
assertEquals(EXPECTED_DATA_DATE_FROM_STRING, String.valueOf(date));
Here's the method that I am testing:
public static Date getDateFromString(String dateAsString) {
return getDateFromString(dateAsString, "dd/MM/yyyy");
}
public static Date getDateFromString(String dateAsString, String dateFormat) {
Date formattedDate = null;
if (StringUtils.notNull(dateAsString)) {
DateFormat format = new SimpleDateFormat(dateFormat);
try {
formattedDate = parseString(dateAsString, format);
} catch (ParseException e) {
try {
formattedDate = parseString(dateAsString, new SimpleDateFormat("yyyy-MM-dd"));
} catch (ParseException e1) {
// handle exception code
}
}
}
return formattedDate;
}
So the unit test is not timezone independent. Is there anyway to set the default timezone just for unit testing?
java.time or Joda-Time
The Date and SimpleDateFormat classes have design problems, so consider not using them. The first version of your question was tagged jodatime, and if you are using Joda-Time in your project, that’s already a sizable improvement. Joda-Time gives you all the functionality you need, so your method should probably return an approrpiate type from Joda-Time rather than an old-fashioned Date.
Joda-Time is also on its way to retirement, though, and its successor is java.time, the modern Java date and time API. So the latter is an option you may consider no matter if you were already using Joda-Time or not. Since your string contains a UTC offset, one option is to return an OffsetDateTime. To test a method that does this:
assertEquals(OffsetDateTime.of(1980, 3, 26, 0, 0, 0, 0, ZoneOffset.ofHours(2)),
DateUtils.getOffsetDateTimeFromString("1980-03-26T00:00:00.000+0200"));
Your example and your code may give the impression that you are only after the date from the string and don’t care about the time of day nor the offset. If this is correct, your method may return a LocalDate and be tested in this way:
assertEquals(LocalDate.of(1980, Month.MARCH, 26),
DateUtils.getLocalDateFromString("1980-03-26T00:00:00.000+0200"));
The latter will also free you from all time zone considerations. In both cases please note that I am passing date-time objects to assertEquals, not strings.
Your unit test is correct: your method is returning the wrong time
The failure you reported in your question was that while the expected Date from your method was Wed Mar 26 00:00:00 PST 1980, the actual value was Wed Mar 26 00:00:00 SGT 1980. It is correct that these differ. Midnight in Baja California, Yukon, Washington, Nevada, California and other places observing Pacific Time is not the same point in time as midnight in China.
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 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.
In case you don’t want your Android code to depend on a third-party library, you can still use java.time in your unit test. To test a method that returns an old-fashioned Date:
Instant expectedInstant = LocalDate.of(1980, Month.MARCH, 26)
.atStartOfDay(ZoneId.systemDefault())
.toInstant();
Date expectedDate = Date.from(expectedInstant);
Date actualDate = DateUtils.getDateFromString("1980-03-26T00:00:00.000+0200");
assertEquals(expectedDate, actualDate);
If using the backport (ThreeTen Backport and/or ThreeTenABP), the conversion from Instantot Date happens a little differently:
Date expectedDate = DateTimeUtil.toDate(expectedInstant);
Again note that I am comparing Date objects, not strings.
How to set the timezone for a SimpleDateFormat?
To answer the question in your title: use the setTimeZone method:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXX");
df.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles")); // Pacific Time
System.out.println(df.parseObject("1980-03-26T00:00:00.000+0200"));
In this particular case it won’t make any difference, though, because the offset in the string is parsed and takes precedence over the time zone of the formatter.
Is there any way to set the default timezone just for unit testing?
There are a couple of options.
TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
Putting this into the beforeClass or before method of your unit test will set the time zone of your JVM to Pacific Time. It’s not bullet-proof since other code may set it to something else before the test finishes, but you may be able to control that that doesn’t happen. Normally I would discourage the use of the outdated TimeZone class. It too has design problems, but is the natural outdated choice if the methods you are testing are using the outdated SimpleDateFormat. One of the problems is it doesn’t report if the string passed is invalid. To obtain proper validation just go through the modern class:
TimeZone.setDefault(TimeZone.getTimeZone(ZoneId.of("America/Los_Angeles")));
Or using the backport:
TimeZone.setDefault(DateTimeUtils.toTimeZone(ZoneId.of("America/Los_Angeles")));
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.

android timestamp parsing gone wrong(always in 1970)

im trying to convert a string(with unix timestamp) to an date with the format ( dd-MM-yyyy)
and this is working partly. The problem im having now is that my date is in 17-01-1970 (instead of march 16 2015)
im converting it like this:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
Date d = null;
int dateMulti = Integer.parseInt(Date);
Calendar cal = Calendar.getInstance(Locale.ENGLISH);
cal.setTimeInMillis(dateMulti);
String date = DateFormat.format("dd-MM-yyyy", cal).toString();
Log.d("test",date);
try {
d = dateFormat.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
where Date = 1427101853
and the result = 17-01-1970
what am i doing wrong?
You are using the wrong format string in the first line:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-mm-yyyy");
mm is minutes. Use MM (months) instead.
edit A Unix timestamp is a number of seconds since 01-01-1970 00:00:00 GMT. Java measures time in milliseconds since 01-01-1970 00:00:00 GMT. You need to multiply the Unix timestamp by 1000:
cal.setTimeInMillis(dateMulti * 1000L);
Why you have "dd-mm-yyyy" in SimpleDateFormat and "dd-MM-yyyy" in DateFormat.format? Use this :
String date = DateFormat.format("dd-mm-yyyy", cal).toString();
If you want minutes, if you want months you have to put MM like #Jesper said :)
I should like to contribute the modern answer.
java.time
DateTimeFormatter dateFormatter = DateTimeFormatter
.ofLocalizedDate(FormatStyle.MEDIUM)
.withLocale(Locale.forLanguageTag("da"));
String unixTimeStampString = "1427101853";
int dateMulti = Integer.parseInt(unixTimeStampString);
ZonedDateTime dateTime = Instant.ofEpochSecond(dateMulti)
.atZone(ZoneId.of("Africa/Conakry"));
String formattedDate = dateTime.format(dateFormatter);
System.out.println(formattedDate);
The output from this snippet is:
23-03-2015
The output agrees with an online converter (link at the bottom). It tells me your timestamp equals “03/23/2015 # 9:10am (UTC)” (it also agrees with the date you asked the question). Please substitute your time zone if it didn’t happen to be Africa/Conakry.
The date-time classes that you were using — SimpleDateFormat, Date and Calendar — are long outdated and poorly designed, so I suggest you skip them and use java.time, the modern Java date and time API, instead. A minor one among the many advantages is it accepts seconds since the epoch directly, so you don’t need to convert to milliseconds. While this was no big deal, doing your own time conversions is a bad habit, you get clearer, more convincing and less error-prone code from leaving the conversions to the appropriate library methods.
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, I’m told) the modern API 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.
I wrote and ran the above snippet using the backport to make sure it would be compatible with ThreeTenABP.
Links
Timestamp Converter
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.
I was also facing the same issue when I was using SimpleDateFormat Here is a method I have made, which is working fine for me.
private String getmDate(long time1) {
java.util.Date time = new java.util.Date((long) time1 * 1000);
String date = DateFormat.format("dd-MMM-yyyy' at 'HH:mm a", time).toString();
return date + "";
}
you can change the date format as you desire.

Getting GMT time with Android

I have been digging into the question for a while in StackOverflow
Android get Current UTC time
and
How can I get the current date and time in UTC or GMT in Java?
I have tried two ways to get the current time of my phone in GMT. I am in Spain and the difference is GMT+2. So let's see with an example:
1º attemp: I created a format and applied it to System.currentTimeMillis();
DateFormat dfgmt = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
dfgmt.setTimeZone(TimeZone.getTimeZone("GMT"));
String gmtTime = dfgmt.format(new Date());
//Using System.currentTimeMillis() is the same as new Date()
Date dPhoneTime = dfgmt.parse(gmtTime);
Long phoneTimeUTC = dPhoneTime.getTime();
I need to substract that time to another time, that's why i do the cast to Long.
DateFormat df = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date arrivalDate = df.parse(item.getArrivalDate());
//the String comes from JSON and is for example:"UTC_arrival":"2011-05-16 18:00:00"
//which already is in UTC format. So the DateFormat doesnt have the GMT paramater as dfgmt
diff = arrival.getTime() - phoneTimeUTC ;
I also tried this:
Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
Long phoneTimeUTC = aGMTCalendar.getTimeInMillis()
And still I dont get the right difference. But if I do this:
Long phoneTimeUTC = aGMTCalendar.getTimeInMillis()-3600000*2;
It does work OK.
Any ideas?
Thanks a lot,
David.
This works for sure!
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(new Date())+"");
Specify the format, and you will get it in GMT!
As far as I read the calendar.getTimeInMillis(); returns the UTC time in millis. I used the following code and compared it to the Epoch in this site http://www.xav.com/time.cgi.
public int GetUnixTime()
{
Calendar calendar = Calendar.getInstance();
long now = calendar.getTimeInMillis();
int utc = (int)(now / 1000);
return (utc);
}
Giora
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
Date currentLocalTime = cal.getTime();
DateFormat date = new SimpleDateFormat("dd-MM-yyy HH:mm:ss z");
date.setTimeZone(TimeZone.getTimeZone("GMT"));
String localTime = date.format(currentLocalTime);
System.out.println(localTime);
Have a look and see if that works.
you can always use:
Calendar mCalendar = Calendar.getInstance(TimeZone.getTimeZone("gmt"));
long millies = mCalendar.getTimeInMillis();
or
Calendar mCalendar = Calendar.getInstance(TimeZone.getTimeZone("utc"));
long millies = mCalendar.getTimeInMillis();
Output: 2016-08-01 14:37:48 UTC
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Works fine.
java.time and ThreeTenABP
I am providing the modern answer.
To get the difference in milliseconds between the phone time now — in Spain or any other place — and a certain time in the past:
// Example arrival time for the demonstration
Instant arrival = Instant.parse("2020-02-29T12:34:56.789Z");
Instant currentTime = Instant.now();
long difference = ChronoUnit.MILLIS.between(arrival, currentTime);
System.out.println("Difference is " + difference + " milliseconds");
Example output:
Difference is 2610350731 milliseconds
If you want the difference in seconds or some other time unit, just use the appropriate enum constant from the ChronoUnit enum instead of ChronoUnit.MILLIS.
There is no need to worry about the device time zone, nor about formatting or parsing the time, those worries only lead to over-complication of this basically simple matter.
BTW the epoch is one well-defined point in time, it doesn’t vary with time zone, it’s the same all over the world. Therefore the count of milliseconds from the epoch till now is also the same in all time zones. Some say that this count is always in UTC because the epoch is (usually) defined in UTC, as January 1, 1970 at 00:00 UTC.
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.

Categories

Resources