How to convert time stamp to get exact milliseconds difference in Android? - android

I have time in this format:
If I have times like Y1 = 05:41:54.771 and Y2 = 05:42:03.465, I want to have exact difference in milliseconds. For the above example the exact millisecond difference would be "6693 milliseconds". How do I achieve this?
Date date = new Date(timestamp);
DateFormat format = new SimpleDateFormat("hh:mm:ss.SSS",Locale.getDefault());
}

The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API.
For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7.
If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Using the modern date-time API:
import java.time.Duration;
import java.time.LocalTime;
public class Main {
public static void main(String[] args) {
long millisBetween = Duration.between(LocalTime.parse("05:41:54.771"), LocalTime.parse("05:42:03.465"))
.toMillis();
System.out.println(millisBetween);
}
}
Output:
8694
Learn more about the modern date-time API from Trail: Date Time.
Using the legacy API:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
DateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS", Locale.ENGLISH);
long millisBetween = sdf.parse("05:42:03.465").getTime() - sdf.parse("05:41:54.771").getTime();
System.out.println(millisBetween);
}
}
Output:
8694
Some important notes about this solution:
Without a date, SimpleDateFormat parses the time string with a date of January 1, 1970 GMT.
Date#getTime returns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object.
Use H instead of h for a time value in 24-Hour format.

You are in the right direction. Using the DateFormat's parse() method you can get a Date object. Then convert it to instant and get the millis since epoch. Finally it's a simple subtraction.
DateFormat format = new SimpleDateFormat("hh:mm:ss.SSS", Locale.getDefault());
try {
Instant y1 = format.parse("05:41:54.771").toInstant();
Instant y2 = format.parse("05:42:03.465").toInstant();
long diffMillis = y2.toEpochMilli() - y1.toEpochMilli();
System.out.println(diffMillis);
} catch (ParseException e) {
throw new RuntimeException(e);
}

The line of code you have provided is a DateFormat object that takes a date and formats it into a string representation. It doesn't have any actual data stored in it. You want to make a comparison on the actual date object, not the formatter.
There are a few different ways to store time, but a common way to store timestamps is as a Long. Since longs are numbers, you can do comparison and math just like an Int:
Long startTime = System.currentTimeMillis();
// Do some long task here that we want to know the duration of
Long endTime = System.currentTimeMillis();
Long difference = endTime - startTime;
Alternatively, there are libraries and tools for dealing with structured time data that may have other ways of storing timestamps and comparing them, however this is a quick example of a common simple implementation if you just need to quickly compare two timestamps.

Related

Converting String to Date generates different results on different devices

I am retrieving a String called date in the form 2018-09-20T17:00:00Z for example and converting it to a Date in the format Thu Oct 20 17:00:00 GMT+01:00 2018 using
SimpleDateFormat dateConvert = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss'Z'", Locale.US);
convertedDate = new Date();
try {
convertedDate = dateConvert.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
On different devices however I am getting different results. One gives Thu Oct 20 17:00:00 BST 2018 (British Summer Time, equivalent to GMT+01:00) but this proves problematic later on. Is there a way to ensure dates are formatted in terms of a GMT offset i.e. GMT+01:00 instead of BST?
java.time
Instant convertInstant = Instant.parse(date);
An Instant (just like a Date) represents a point in time independently of time zone. So you’re fine. As an added bonus your String of 2018-09-20T17:00:00Z is in the ISO 8601 format for an instant, so the Instant class parses it without the need for specifying the format.
EDIT: To format it into a human readable string in British Summer Time with unambiguous UTC offset use for example:
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK);
ZonedDateTime dateTime = convertInstant.atZone(ZoneId.of("Europe/London"));
String formatted = dateTime.format(formatter);
System.out.println(formatted);
This code snippet printed:
Thu Sep 20 18:00:00 +0100 2018
18:00 is the correct time at offset +01:00. The Z at the end of the original string means offset zero, AKA “Zulu time zone”, and 17 at offset zero is the same point in time as 18:00 at offset +01:00. I took over the format pattern string from your own answer.
EDIT 2
I wanted to present to you my suggestion for rewriting the Fixture class from your own answer:
public class Fixture implements Comparable<Fixture> {
private static DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK);
public Instant date;
/** #param date Date string from either web service or persistence */
public Fixture(String date) {
this.date = Instant.parse(date);
}
/** #return a string for persistence, e.g., Firebase */
public String getDateForPersistence() {
return date.toString();
}
/** #return a string for the user in the default time zone of the device */
public String getFormattedDate() {
return date.atZone(ZoneId.systemDefault()).format(formatter);
}
#Override
public int compareTo(Fixture other) {
return date.compareTo(other.date);
}
#Override
public String toString() {
return "Fixture [date=" + date + "]";
}
}
This class has a natural ordering (namely by date and time) in that it implements Comparable, meaning you no longer need your DateSorter class. A few lines of code to demonstrate the use of the new getXx methods:
String date = "2018-09-24T11:30:00Z";
Fixture fixture = new Fixture(date);
System.out.println("Date for user: " + fixture.getFormattedDate());
System.out.println("Date for Firebase: " + fixture.getDateForPersistence());
When I ran this snippet in Europe/London time zone I got:
Date for user: Mon Sep 24 12:30:00 +0100 2018
Date for Firebase: 2018-09-24T11:30:00Z
So the user gets the date and time with his or her own offset from UTC as I think you asked for. Trying the same snippet in Europe/Berlin time zone:
Date for user: Mon Sep 24 13:30:00 +0200 2018
Date for Firebase: 2018-09-24T11:30:00Z
We see that the user in Germany is told that the match is at 13:30 rather than 12:30, which agrees with his or her clock. The date to be persisted in Firebase is unchanged, which is also what you want.
What went wrong in your code
There are two bugs in your format pattern string, yyyy-MM-dd'T'hh:mm:ss'Z':
Lowercase hh is for hour within AM or PM from 01 through 12 and only meaningful with an AM/PM marker. In practice you will get the correct result except when parsing an hour of 12, which will be understood as 00.
By parsing Z as a literal you are not getting the UTC offset information from the string. Instead SimpleDateFormat will use the time zone setting of the JVM. This obviously differs from one device to the other and explains why you got different and conflicting results in different devices.
The other thing going on in your code is the peculiar behaviour of Date.toString: this method grabs the JVM’s time zone setting and uses it for generating the string. So when one device is set to Europe/London and another to GMT+01:00, then equal Date objects will be rendered differently on those devices. This behaviour has confused many.
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). The code above was developed and run with org.threeten.bp.Duration from the backport.
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
You are just doing step 1 of a two step process:
Parse the date to convert it to a Date object
Take this parsed Date object and format it using SimpleDateFormat again.
So, you've done step one correctly, here's what you have to do with step 2, try this:
final String formattedDateString = new SimpleDateFormat("EEE MMM dd HH:mm:ss 'GMT'XXX yyyy").format(convertedDate);
Source
So just to add a bit of an update here. The answers that people have provided have helped massively and I now have a code that does exactly what I want, but the term 'legacy' in one of the comments makes me feel that there may be a better and longer-lasting way. Here's what currently happens in the code.
1) I fetch a football fixture which comes with a String utc date in the form 2018-09-22T11:30:00Z
2) I then parse the date using SimpleDateFormat convertUtcDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); and convertUtcDate.setTimeZone(TimeZone.getTimeZone("GMT"));
3) I then get the current time using currentTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")).getTime(); and compare the two using if(convertedDate.after(currentTime)) to find a team's next fixture. At this point I have found that a device will have these two dates in the same form, either with BST or GMT+01:00 but either way the two dates can be accurately compared.
4) I then format the date so it is in terms of a GMT offset using SimpleDateFormat convertToGmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US); and String dateString = convertToGmt.format(convertedDate);
5) For the utc date in 1) this returns Sat Sep 22 12:30:00 GMT+01:00 2018 regardless of the device. Notice that the time is different to the utc date. Not quite sure why this is the case (could be because the guy running the API is based in Germany which is an hour ahead of me here in England) but the important thing is that this time is correct (it refers to the Fulham - Watford game tomorrow which is indeed at 12:30 BST/GMT+01:00).
6) I then send this String along with a few other bits of information about the fixture to Firebase. It is important that the date be in the form GMT+01:00 rather than BST at this point because other devices may not recognise the BST form when they read that information.
7) When it comes to calling that information back from Firebase, I convert it back to a date by parsing it using SimpleDateFormat String2Date = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.US); and then I can arrange the fixtures in chronological order by comparing their dates.
I would just like to reiterate that this method works. I have checked for fixtures when the time zone in England changes back to GMT+00:00 and it still works fine. I have tried to make sure that everything is done in terms of GMT so that it would work anywhere. I cannot be sure though that this would be the case. Does anyone see any flaws in this method? Could it be improved?
Edit: Here is a snippet of the code which I hope simply and accurately represents what I am doing.
public class FragmentFixture extends Fragment {
SimpleDateFormat convertUtcDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
SimpleDateFormat String2Date = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.US);
SimpleDateFormat convertToGmt = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
private List<Fixture> fixtureList;
Date date1;
Date date2;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
convertUtcDate.setTimeZone(TimeZone.getTimeZone("GMT"));
fixtureList = new ArrayList<>();
// retrieve fixtures from API and get date for a certain fixture. I will provide an example
String date = "2018-09-22T11:30:00Z";
Date convertedDate = new Date();
try {
convertedDate = convertUtcDate.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
Date currentTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")).getTime();
if (convertedDate.after(currentTime)) {
String dateString = convertToGmt.format(convertedDate);
Fixture fixture = new Fixture(dateString);
fixtureList.add(fixture);
Collections.sort(fixtureList, new DateSorter());
}
}
public class DateSorter implements Comparator<Fixture> {
#Override
public int compare(Fixture fixture, Fixture t1) {
try {
date1 = String2Date.parse(fixture.getDate());
} catch (ParseException e) {
e.printStackTrace();
}
try {
date2 = String2Date.parse(t1.getDate());
} catch (ParseException e) {
e.printStackTrace();
}
return date1.compareTo(date2);
}
}
public class Fixture {
public String date;
public Fixture() {
}
public Fixture(String date) {
this.date = date;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
}

OffsetDateTime to Date Android

I am getting an OffsetDateTime from our backend in a String format like this:
"2017-07-15T10:52:59Z"
I am trying to parse this String to a Android Date:
private SimpleDateFormat mSimpleDateFormat;
private static final String DATE_FORMAT_PATTERN = "yyyy-MM-dd'T'HH:mm:ss";
mSimpleDateFormat = new SimpleDateFormat(DATE_FORMAT_PATTERN, Locale.getDefault());
Date newDate = null;
String dateString = notice.getCreated();
try {
newDate = mSimpleDateFormat.parse(dateString);
} catch (ParseException e) {
LogHelper.showExceptionLog(MyClass.class, e);
}
It always throws:
Unparseable date: "2017-07-15T10:52:59Z"
To parse the Z (which is the UTC designator) you must use the X pattern (as explained in javadoc):
SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
String dateString = "2017-07-15T10:52:59Z";
Date newDate = mSimpleDateFormat.parse(dateString);
If you use just yyyy-MM-dd'T'HH:mm:ss as a pattern, SimpleDateFormat will use the system's default timezone and ignore the Z, giving incorrect results: it'll parse the date/time as 10:52 in the default timezone, which can be different to 10:52 in UTC. By using the X pattern, you get the correct result.
I also removed the Locale because this formatter is not dealing with any locale-sensitive information (like month and day of week names), so it doesn't affect the parsing in this case (and SimpleDateFormat already uses the default locale if you don't specify one).
PS: the X pattern was introduced in JDK 7. If you're using and older version, it won't be available. In this case, you can set the UTC as a timezone of the formatter:
SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
mSimpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Obviously this code is assuming that the input is always in UTC (with Z in the end).
Java new Date/Time API
The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.
For Android, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. To make it work, you'll also need ThreeTenABP (more on how to use it here).
As the input string is in ISO 8601 format, you can easily parse it to a org.threeten.bp.OffsetDateTime:
String dateString = "2017-07-15T10:52:59Z";
OffsetDateTime odt = OffsetDateTime.parse(dateString);
You can then convert this to a java.util.Date easily, using the org.threeten.bp.DateTimeUtils class:
Date date = DateTimeUtils.toDate(odt.toInstant());
If the input is always in UTC (always with the Z in the end), you can also use a org.threeten.bp.Instant:
String dateString = "2017-07-15T10:52:59Z";
Instant instant = Instant.parse(dateString);
Date date = DateTimeUtils.toDate(instant);
The only difference is that Instant only parses UTC inputs (ending with Z) and OffsetDateTime accepts any valid UTC offset (like -03:00 or +05:30).

Difference between two datetime formats in android?

As i am new to android development I am unable to find code for calculating the difference between two datetime formats. My question is.
I am using webservice in my project where i am getting datetime response as follows..
starttime :- [2012-11-04 10:00:00]
endtime :- [2012-11-04 12:00:00]
Here i want to display on screen as
Today Timings :- 2012-11-04 2 hours
Means need to calculate the difference between two dates and need to display the time difference on screen.
Can anyone please help me with this.
Given you know the exact format in which you are getting the date-time object, you could use the SimpleDateFormat class in Android which allows you to parse a string as a date given the format of the date expressed in the string. For your question:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date startTime = sdf.parse(<startTime/endTime String>, 0);
Similarly parse your endtime, and then the difference can be obtained using getTime() of the individual objects.
long diff = endTime.getTime() - startTime.getTime()
Then it's as simple as converting the difference to hours using:
int hours = (int)(diff/(60*60*1000));
Hope that helps.
java.time
Solution using java.time, the modern API:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH);
LocalDateTime startTime = LocalDateTime.parse("2012-11-04 10:00:00", dtf);
LocalDateTime endTime = LocalDateTime.parse("2012-11-04 12:00:00", dtf);
long hours = ChronoUnit.HOURS.between(startTime, endTime);
System.out.println(hours);
}
}
Output:
2
Learn more about the the modern date-time API* from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
If you're using java.util.Date; you're gonna have to use an intermediate variable. you can convert your dates to long values and subtract those and then convert your long back to a date.
long diff = new Date().getTime() - new Date(milliseconds).getTime();
Date dateDiff = new Date(diff);
But you should be warned that it doesn't take daylight savings and whatever else variables into account. if you're that scrupulous, you might be indulged with this replacement date class. It has the functionality you seek.
I use this code to get difference of two date.
public void getTimeDifference(Date endDate,Date startDate) {
Date diff = new Date(endDate.getTime() - startDate.getTime());
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calendar.setTime(diff);
int day=calendar.get(Calendar.DAY_OF_MONTH);
int hours = calendar.get(Calendar.HOUR_OF_DAY);
}
}

converting long string to date [duplicate]

This question already has answers here:
Unfortunately MyApp has stopped. How can I solve this?
(23 answers)
Convert UTC Epoch to local date
(16 answers)
How to convert String to long in Java?
(10 answers)
Closed 1 year ago.
I am getting date value from DB as a long value. I am converting this to string to use parse function. Given below is my code
Date date1 = new SimpleDateFormat("MM/dd/yyyy").parse(strDate1);
But the app is crashing when this code is executing.it will successfully execute if the
strDate1="12/30/2012".
But i am having this value as "12302012235"(pzudo value).
How can i do this?
edit:
i am saving date value to DB as INTEGER. from DB i am getting this value and converting to string.this is the actual strDate1 value
strDate1="1346524199000"
Try the following code segment:
Calendar c = Calendar.getInstance();
c.setTimeInMillis(Long.parseLong(val));
Date d = (Date) c.getTime();
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
String time = format.format(d);//this variable time contains the time in the format of "day/month/year".
Try this,
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
Date dateD=new Date();
dateD.setTime(LongTime);
date=dateFormat.format(dateD);
Java 8, Convert milliseconds long to Date as String by given date format pattern. If you have a long milliseconds and want to convert them into date string at specifies time zone and pattern, then you can use it:-
dateInMs is a long value of DateTime.
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
.format(Instant.ofEpochMilli(dateInMs).atZone(ZoneId.of("Europe/London")))
java.time
The java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API* .
Using modern date-time API:
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
long input = 12302012235L;
// Get Instant from input
Instant instant = Instant.ofEpochMilli(input);
System.out.println(instant);
// Convert Instant to ZonedDateTime by applying time-zone
// Change ZoneId as applicable e.g. ZoneId.of("Asia/Dubai")
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
System.out.println(zdt);
// Format ZonedDateTime as desired
// Check https://stackoverflow.com/a/65928023/10819573 to learn more about 'u'
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/uuuu", Locale.ENGLISH);
String formatted = dtf.format(zdt);
System.out.println(formatted);
// If at all, you need java.util.Date
Date date = Date.from(instant);
}
}
Output:
1970-05-23T09:13:32.235Z
1970-05-23T10:13:32.235+01:00[Europe/London]
05/23/1970
Learn more about the modern date-time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
You can try following code:
private Date getGMTDate(long date) {
SimpleDateFormat dateFormatGmt = new SimpleDateFormat(
"yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
SimpleDateFormat dateFormatLocal = new SimpleDateFormat(
"yyyy-MMM-dd HH:mm:ss");
Date temp = new Date(date);
try {
return dateFormatLocal.parse(dateFormatGmt.format(temp));
} catch (ParseException e) {
e.printStackTrace();
}
return temp;
}
I hope this will help you.
Try this
Date date1 = new SimpleDateFormat("MMddyyyySSS").parse(strDate1);
Hope it will works for 12302012235 , but i assume 235 is millisec.
i got the answer.actually i wanted to convert the string to date only for comparing the values.since i am getting the value as long i directly used the compareTo function to do this.avoided the conversion of long to string and string to date conversion.thank you all for support.

How to conert local time to UTC time in android [duplicate]

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
When I create a new Date object, it is initialized to the current time but in the local timezone. How can I get the current date and time in GMT?
tl;dr
Instant.now() // Capture the current moment in UTC.
Generate a String to represent that value:
Instant.now().toString()
2016-09-13T23:30:52.123Z
Details
As the correct answer by Jon Skeet stated, a java.util.Date object has no time zone†. But its toString implementation applies the JVM’s default time zone when generating the String representation of that date-time value. Confusingly to the naïve programmer, a Date seems to have a time zone but does not.
The java.util.Date, j.u.Calendar, and java.text.SimpleDateFormat classes bundled with Java are notoriously troublesome. Avoid them. Instead, use either of these competent date-time libraries:
java.time.* package in Java 8
Joda-Time
java.time (Java 8)
Java 8 brings an excellent new java.time.* package to supplant the old java.util.Date/Calendar classes.
Getting current time in UTC/GMT is a simple one-liner…
Instant instant = Instant.now();
That Instant class is the basic building block in java.time, representing a moment on the timeline in UTC with a resolution of nanoseconds.
In Java 8, the current moment is captured with only up to milliseconds resolution. Java 9 brings a fresh implementation of Clock captures the current moment in up to the full nanosecond capability of this class, depending on the ability of your host computer’s clock hardware.
It’s toString method generates a String representation of its value using one specific ISO 8601 format. That format outputs zero, three, six or nine digits digits (milliseconds, microseconds, or nanoseconds) as necessary to represent the fraction-of-second.
If you want more flexible formatting, or other additional features, then apply an offset-from-UTC of zero, for UTC itself (ZoneOffset.UTC constant) to get a OffsetDateTime.
OffsetDateTime now = OffsetDateTime.now( ZoneOffset.UTC );
Dump to console…
System.out.println( "now.toString(): " + now );
When run…
now.toString(): 2014-01-21T23:42:03.522Z
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Joda-Time
UPDATE: The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
Using the Joda-Time 3rd-party open-source free-of-cost library, you can get the current date-time in just one line of code.
Joda-Time inspired the new java.time.* classes in Java 8, but has a different architecture. You may use Joda-Time in older versions of Java. Joda-Time continues to work in Java 8 and continues to be actively maintained (as of 2014). However, the Joda-Time team does advise migration to java.time.
System.out.println( "UTC/GMT date-time in ISO 8601 format: " + new org.joda.time.DateTime( org.joda.time.DateTimeZone.UTC ) );
More detailed example code (Joda-Time 2.3)…
org.joda.time.DateTime now = new org.joda.time.DateTime(); // Default time zone.
org.joda.time.DateTime zulu = now.toDateTime( org.joda.time.DateTimeZone.UTC );
Dump to console…
System.out.println( "Local time in ISO 8601 format: " + now );
System.out.println( "Same moment in UTC (Zulu): " + zulu );
When run…
Local time in ISO 8601 format: 2014-01-21T15:34:29.933-08:00
Same moment in UTC (Zulu): 2014-01-21T23:34:29.933Z
For more example code doing time zone work, see my answer to a similar question.
Time Zone
I recommend you always specify a time zone rather than relying implicitly on the JVM’s current default time zone (which can change at any moment!). Such reliance seems to be a common cause of confusion and bugs in date-time work.
When calling now() pass the desired/expected time zone to be assigned. Use the DateTimeZone class.
DateTimeZone zoneMontréal = DateTimeZone.forID( "America/Montreal" );
DateTime now = DateTime.now( zoneMontréal );
That class holds a constant for UTC time zone.
DateTime now = DateTime.now( DateTimeZone.UTC );
If you truly want to use the JVM’s current default time zone, make an explicit call so your code is self-documenting.
DateTimeZone zoneDefault = DateTimeZone.getDefault();
ISO 8601
Read about ISO 8601 formats. Both java.time and Joda-Time use that standard’s sensible formats as their defaults for both parsing and generating strings.
† Actually, java.util.Date does have a time zone, buried deep under layers of source code. For most practical purposes, that time zone is ignored. So, as shorthand, we say java.util.Date has no time zone. Furthermore, that buried time zone is not the one used by Date’s toString method; that method uses the JVM’s current default time zone. All the more reason to avoid this confusing class and stick with Joda-Time and java.time.
java.util.Date has no specific time zone, although its value is most commonly thought of in relation to UTC. What makes you think it's in local time?
To be precise: the value within a java.util.Date is the number of milliseconds since the Unix epoch, which occurred at midnight January 1st 1970, UTC. The same epoch could also be described in other time zones, but the traditional description is in terms of UTC. As it's a number of milliseconds since a fixed epoch, the value within java.util.Date is the same around the world at any particular instant, regardless of local time zone.
I suspect the problem is that you're displaying it via an instance of Calendar which uses the local timezone, or possibly using Date.toString() which also uses the local timezone, or a SimpleDateFormat instance, which, by default, also uses local timezone.
If this isn't the problem, please post some sample code.
I would, however, recommend that you use Joda-Time anyway, which offers a much clearer API.
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
//Local time zone
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
//Time in GMT
return dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
This definitely returns UTC time: as String and Date objects !
static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static Date getUTCdatetimeAsDate() {
// note: doesn't check for null
return stringDateToDate(getUTCdatetimeAsString());
}
public static String getUTCdatetimeAsString() {
final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
final String utcTime = sdf.format(new Date());
return utcTime;
}
public static Date stringDateToDate(String StrDate) {
Date dateToReturn = null;
SimpleDateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);
try {
dateToReturn = (Date)dateFormat.parse(StrDate);
}
catch (ParseException e) {
e.printStackTrace();
}
return dateToReturn;
}
Calendar c = Calendar.getInstance();
System.out.println("current: "+c.getTime());
TimeZone z = c.getTimeZone();
int offset = z.getRawOffset();
if(z.inDaylightTime(new Date())){
offset = offset + z.getDSTSavings();
}
int offsetHrs = offset / 1000 / 60 / 60;
int offsetMins = offset / 1000 / 60 % 60;
System.out.println("offset: " + offsetHrs);
System.out.println("offset: " + offsetMins);
c.add(Calendar.HOUR_OF_DAY, (-offsetHrs));
c.add(Calendar.MINUTE, (-offsetMins));
System.out.println("GMT Time: "+c.getTime());
Actually not time, but it's representation could be changed.
SimpleDateFormat f = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(f.format(new Date()));
Time is the same in any point of the Earth, but our perception of time could be different depending on location.
This works for getting UTC milliseconds in Android.
Calendar c = Calendar.getInstance();
int utcOffset = c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET);
Long utcMilliseconds = c.getTimeInMillis() + utcOffset;
Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
Then all operations performed using the aGMTCalendar object will be done with the GMT time zone and will not have the daylight savings time or fixed offsets applied
Wrong!
Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
aGMTCalendar.getTime(); //or getTimeInMillis()
and
Calendar aNotGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));aNotGMTCalendar.getTime();
will return the same time. Idem for
new Date(); //it's not GMT.
This code prints the current time UTC.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Test
{
public static void main(final String[] args) throws ParseException
{
final SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(f.format(new Date()));
}
}
Result
2013-10-26 14:37:48 UTC
Here is what seems to be incorrect in Jon Skeet's answer. He said:
java.util.Date is always in UTC. What makes you think it's in local
time? I suspect the problem is that you're displaying it via an
instance of Calendar which uses the local timezone, or possibly using
Date.toString() which also uses the local timezone.
However, the code:
System.out.println(new java.util.Date().getHours() + " hours");
gives the local hours, not GMT (UTC hours), using no Calendar and no SimpleDateFormat at all.
That is why is seems something is incorrect.
Putting together the responses, the code:
System.out.println(Calendar.getInstance(TimeZone.getTimeZone("GMT"))
.get(Calendar.HOUR_OF_DAY) + " Hours");
shows the GMT hours instead of the local hours -- note that getTime.getHours() is missing because that would create a Date() object, which theoretically stores the date in GMT, but gives back the hours in the local time zone.
If you want a Date object with fields adjusted for UTC you can do it like this with Joda Time:
import org.joda.time.DateTimeZone;
import java.util.Date;
...
Date local = new Date();
System.out.println("Local: " + local);
DateTimeZone zone = DateTimeZone.getDefault();
long utc = zone.convertLocalToUTC(local.getTime(), false);
System.out.println("UTC: " + new Date(utc));
You can use:
Calendar aGMTCalendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
Then all operations performed using the aGMTCalendar object will be done with the GMT time zone and will not have the daylight savings time or fixed offsets applied. I think the previous poster is correct that the Date() object always returns a GMT it's not until you go to do something with the date object that it gets converted to the local time zone.
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MM-dd");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(date));
Here is my implementation of toUTC:
public static Date toUTC(Date date){
long datems = date.getTime();
long timezoneoffset = TimeZone.getDefault().getOffset(datems);
datems -= timezoneoffset;
return new Date(datems);
}
There's probably several ways to improve it, but it works for me.
You can directly use this
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dateFormatGmt.format(new Date())+"");
Here an other suggestion to get a GMT Timestamp object:
import java.sql.Timestamp;
import java.util.Calendar;
...
private static Timestamp getGMT() {
Calendar cal = Calendar.getInstance();
return new Timestamp(cal.getTimeInMillis()
-cal.get(Calendar.ZONE_OFFSET)
-cal.get(Calendar.DST_OFFSET));
}
Here is another way to get GMT time in String format
String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss z" ;
final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String dateTimeString = sdf.format(new Date());
With:
Calendar cal = Calendar.getInstance();
Then cal have the current date and time.
You also could get the current Date and Time for timezone with:
Calendar cal2 = Calendar.getInstance(TimeZone.getTimeZone("GMT-2"));
You could ask cal.get(Calendar.DATE); or other Calendar constant about others details.
Date and Timestamp are deprecated in Java. Calendar class it isn't.
Sample code to render system time in a specific time zone and a specific format.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class TimZoneTest {
public static void main (String[] args){
//<GMT><+/-><hour>:<minutes>
// Any screw up in this format, timezone defaults to GMT QUIETLY. So test your format a few times.
System.out.println(my_time_in("GMT-5:00", "MM/dd/yyyy HH:mm:ss") );
System.out.println(my_time_in("GMT+5:30", "'at' HH:mm a z 'on' MM/dd/yyyy"));
System.out.println("---------------------------------------------");
// Alternate format
System.out.println(my_time_in("America/Los_Angeles", "'at' HH:mm a z 'on' MM/dd/yyyy") );
System.out.println(my_time_in("America/Buenos_Aires", "'at' HH:mm a z 'on' MM/dd/yyyy") );
}
public static String my_time_in(String target_time_zone, String format){
TimeZone tz = TimeZone.getTimeZone(target_time_zone);
Date date = Calendar.getInstance().getTime();
SimpleDateFormat date_format_gmt = new SimpleDateFormat(format);
date_format_gmt.setTimeZone(tz);
return date_format_gmt.format(date);
}
}
Output
10/08/2011 21:07:21
at 07:37 AM GMT+05:30 on 10/09/2011
at 19:07 PM PDT on 10/08/2011
at 23:07 PM ART on 10/08/2011
Just to make this simpler, to create a Date in UTC you can use Calendar :
Calendar.getInstance(TimeZone.getTimeZone("UTC"));
Which will construct a new instance for Calendar using the "UTC" TimeZone.
If you need a Date object from that calendar you could just use getTime().
Converting Current DateTime in UTC:
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
DateTimeZone dateTimeZone = DateTimeZone.getDefault(); //Default Time Zone
DateTime currDateTime = new DateTime(); //Current DateTime
long utcTime = dateTimeZone.convertLocalToUTC(currDateTime .getMillis(), false);
String currTime = formatter.print(utcTime); //UTC time converted to string from long in format of formatter
currDateTime = formatter.parseDateTime(currTime); //Converted to DateTime in UTC
public static void main(String args[]){
LocalDate date=LocalDate.now();
System.out.println("Current date = "+date);
}
This worked for me, returns the timestamp in GMT!
Date currDate;
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT"));
SimpleDateFormat dateFormatLocal = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss");
long currTime = 0;
try {
currDate = dateFormatLocal.parse( dateFormatGmt.format(new Date()) );
currTime = currDate.getTime();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The Simple Function that you can use:
Edit: this version uses the modern java.time classes.
private static final DateTimeFormatter FORMATTER
= DateTimeFormatter.ofPattern("dd-MM-uuuu HH:mm:ss z");
public static String getUtcDateTime() {
return ZonedDateTime.now(ZoneId.of("Etc/UTC")).format(FORMATTER);
}
Return value from the method:
26-03-2022 17:38:55 UTC
Original function:
public String getUTC_DateTime() {
SimpleDateFormat dateTimeFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss z");
dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));//gmt
return dateTimeFormat.format(new Date());
}
return of above function:
26-03-2022 08:07:21 UTC
To put it simple. A calendar object stores information about time zone but when you perform cal.getTime() then the timezone information will be lost. So for Timezone conversions I will advice to use DateFormat classes...
this is my implementation:
public static String GetCurrentTimeStamp()
{
Calendar cal=Calendar.getInstance();
long offset = cal.getTimeZone().getOffset(System.currentTimeMillis());//if you want in UTC else remove it .
return new java.sql.Timestamp(System.currentTimeMillis()+offset).toString();
}
Use this Class to get ever the right UTC Time from a Online NTP Server:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
class NTP_UTC_Time
{
private static final String TAG = "SntpClient";
private static final int RECEIVE_TIME_OFFSET = 32;
private static final int TRANSMIT_TIME_OFFSET = 40;
private static final int NTP_PACKET_SIZE = 48;
private static final int NTP_PORT = 123;
private static final int NTP_MODE_CLIENT = 3;
private static final int NTP_VERSION = 3;
// Number of seconds between Jan 1, 1900 and Jan 1, 1970
// 70 years plus 17 leap days
private static final long OFFSET_1900_TO_1970 = ((365L * 70L) + 17L) * 24L * 60L * 60L;
private long mNtpTime;
public boolean requestTime(String host, int timeout) {
try {
DatagramSocket socket = new DatagramSocket();
socket.setSoTimeout(timeout);
InetAddress address = InetAddress.getByName(host);
byte[] buffer = new byte[NTP_PACKET_SIZE];
DatagramPacket request = new DatagramPacket(buffer, buffer.length, address, NTP_PORT);
buffer[0] = NTP_MODE_CLIENT | (NTP_VERSION << 3);
writeTimeStamp(buffer, TRANSMIT_TIME_OFFSET);
socket.send(request);
// read the response
DatagramPacket response = new DatagramPacket(buffer, buffer.length);
socket.receive(response);
socket.close();
mNtpTime = readTimeStamp(buffer, RECEIVE_TIME_OFFSET);
} catch (Exception e) {
// if (Config.LOGD) Log.d(TAG, "request time failed: " + e);
return false;
}
return true;
}
public long getNtpTime() {
return mNtpTime;
}
/**
* Reads an unsigned 32 bit big endian number from the given offset in the buffer.
*/
private long read32(byte[] buffer, int offset) {
byte b0 = buffer[offset];
byte b1 = buffer[offset+1];
byte b2 = buffer[offset+2];
byte b3 = buffer[offset+3];
// convert signed bytes to unsigned values
int i0 = ((b0 & 0x80) == 0x80 ? (b0 & 0x7F) + 0x80 : b0);
int i1 = ((b1 & 0x80) == 0x80 ? (b1 & 0x7F) + 0x80 : b1);
int i2 = ((b2 & 0x80) == 0x80 ? (b2 & 0x7F) + 0x80 : b2);
int i3 = ((b3 & 0x80) == 0x80 ? (b3 & 0x7F) + 0x80 : b3);
return ((long)i0 << 24) + ((long)i1 << 16) + ((long)i2 << 8) + (long)i3;
}
/**
* Reads the NTP time stamp at the given offset in the buffer and returns
* it as a system time (milliseconds since January 1, 1970).
*/
private long readTimeStamp(byte[] buffer, int offset) {
long seconds = read32(buffer, offset);
long fraction = read32(buffer, offset + 4);
return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000L) / 0x100000000L);
}
/**
* Writes 0 as NTP starttime stamp in the buffer. --> Then NTP returns Time OFFSET since 1900
*/
private void writeTimeStamp(byte[] buffer, int offset) {
int ofs = offset++;
for (int i=ofs;i<(ofs+8);i++)
buffer[i] = (byte)(0);
}
}
And use it with:
long now = 0;
NTP_UTC_Time client = new NTP_UTC_Time();
if (client.requestTime("pool.ntp.org", 2000)) {
now = client.getNtpTime();
}
If you need UTC Time "now" as DateTimeString use function:
private String get_UTC_Datetime_from_timestamp(long timeStamp){
try{
Calendar cal = Calendar.getInstance();
TimeZone tz = cal.getTimeZone();
int tzt = tz.getOffset(System.currentTimeMillis());
timeStamp -= tzt;
// DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault());
DateFormat sdf = new SimpleDateFormat();
Date netDate = (new Date(timeStamp));
return sdf.format(netDate);
}
catch(Exception ex){
return "";
}
}
and use it with:
String UTC_DateTime = get_UTC_Datetime_from_timestamp(now);
If you want to avoid parsing the date and just want a timestamp in GMT, you could use:
final Date gmt = new Timestamp(System.currentTimeMillis()
- Calendar.getInstance().getTimeZone()
.getOffset(System.currentTimeMillis()));
public class CurrentUtcDate
{
public static void main(String[] args) {
Date date = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("UTC Time is: " + dateFormat.format(date));
}
}
Output:
UTC Time is: 22-01-2018 13:14:35
You can change the date format as needed.
Current date in the UTC
Instant.now().toString().replaceAll("T.*", "");

Categories

Resources