Difference between two datetime formats in android? - 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);
}
}

Related

How to convert time stamp to get exact milliseconds difference in 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.

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).

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.

Date formatting based on user locale on android

I want to display a date of birth based on the user locale. In my application, one of my fields is the date of birth, which is currently in the format dd/mm/yyyy. So if the user changes his locale, the date format should also change accordingly. Any pointers or code samples would really help me to overcome the problem.
You can use the DateFormat class that formats a date according to the user locale.
Example:
String dateOfBirth = "26/02/1974";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = null;
try {
date = sdf.parse(dateOfBirth);
} catch (ParseException e) {
// handle exception here !
}
java.text.DateFormat dateFormat = android.text.format.DateFormat.getDateFormat(context);
String s = dateFormat.format(date);
You can use the different methods getLongDateFormat, getMediumDateFormat depending on the level of verbosity you would like to have.
While the accepted answer was correct when the question was asked, it has later become outdated. I am contributing the modern answer.
java.time and ThreeTenABP
DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
LocalDate dateOfBirth = LocalDate.of(1991, Month.OCTOBER, 13);
String formattedDob = dateOfBirth.format(dateFormatter);
System.out.println("Born: " + formattedDob);
It gives different output depending on the locale setting of the JVM (usually taking from the device). For example:
Canadian French: Born: 91-10-13
Chinese: Born: 1991/10/13
German: Born: 13.10.91
Italian: Born: 13/10/91
If you want a longer format, you may specify a different format style. Example outputs in US English locale:
FormatStyle.SHORT: Born: 10/13/91
FormatStyle.MEDIUM: Born: Oct 13, 1991
FormatStyle.LONG: Born: October 13, 1991
FormatStyle.FULL: Born: Thursday, October 13, 1991
Question: Can I use java.time on Android?
DateTimeFormatter.ofLocalizedDate requires Api O minimum.
Yes, java.time works nicely on older and newer Android devices. No, it does not require API level 26 or Oreo even though a message in your Android Studio might have you think that. 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 either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.
Question: Can I also accept user input in the user’s local format?
Yes, you can. The formatter can also be used for parsing a string from the user into a LocalDate:
LocalDate date = LocalDate.parse(userInputString, dateFormatter);
I suggest that you first format an example date and show it to the user so that s/he can see which format your program expects for his/her locale. As example date take a date with day of month greater than 12 and year greater than 31 so that the order of day, month and year can be seen from the example (for longer formats the year doesn’t matter since it will be four digits).
Parsing will throw a DateTimeParseException if the user entered the date in an incorrect format or a non-valid date. Catch it and allow the user to try again.
Question: Can I do likewise with a time of day? A date and time?
Yes. For formatting a time of day according to a user’s locale, get a formatter from DateTimeFormatter.ofLocalizedTime. For both date and time together use one of the overloaded versions of DateTimeFormatter.ofLocalizedDateTime.
Avoid the DateFormat, SImpleDateFormat and Date classes
I recommend you don’t use DateFormat, SimpleDateFormat and Date. Those classes are poorly designed and long outdated, the first two in particular notoriously troublesome. Instead use LocalDate, DateTimeFormatter and other classes from java.time, the modern Java date and time API.
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).
Java 8+ APIs available through desugaring
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
As simple as
For date + time:
DateFormat format = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.SHORT, Locale.getDefault());
For just date:
DateFormat format = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
Android api provide easy way to display localized date format.
The following code works.
public class FileDateUtil {
public static String getModifiedDate(long modified) {
return getModifiedDate(Locale.getDefault(), modified);
}
public static String getModifiedDate(Locale locale, long modified) {
SimpleDateFormat dateFormat = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
dateFormat = new SimpleDateFormat(getDateFormat(locale));
} else {
dateFormat = new SimpleDateFormat("MMM/dd/yyyy hh:mm:ss aa");
}
return dateFormat.format(new Date(modified));
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public static String getDateFormat(Locale locale) {
return DateFormat.getBestDateTimePattern(locale, "MM/dd/yyyy hh:mm:ss aa");
}
}
You can check following code.
String koreaData = FileDateUtil.getModifiedDate(Locale.KOREA, System.currentTimeMillis());
String franceData = FileDateUtil.getModifiedDate(Locale.FRENCH, System.currentTimeMillis());
String defaultData = FileDateUtil.getModifiedDate(Locale.getDefault(), System.currentTimeMillis());
String result = "Korea : " + koreaData + System.getProperty("line.separator");
result += "France : " + franceData + System.getProperty("line.separator");
result += "Default : " + defaultData + System.getProperty("line.separator");
tv.setText(result);
To change the date format according to the locale, the following code worked to me:
String dateOfBirth = "26/02/1974";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date date = null;
try {
date = sdf.parse(dateOfBirth);
} catch (ParseException e) {
// handle exception here !
}
String myString = DateFormat.getDateInstance(DateFormat.SHORT).format(date);
Then when you change the locale, the date format will change based on it.
For more information about the dates patterns:
http://docs.oracle.com/javase/tutorial/i18n/format/dateFormat.html
To get the date format pattern you can do :
Format dateFormat = android.text.format.DateFormat.getDateFormat(getApplicationContext());
String pattern = ((SimpleDateFormat) dateFormat).toLocalizedPattern();
After that, you can format your input as per the pattern.
The simple way to do it:
String AR_Format = "dd-mm-yyyy";
String EN_Format = "mm-dd-yyyy";
String getFomattedDateByLocale(Date date, String locale) {
return new SimpleDateFormat(strDateFormat, new Locale(locale)).format(date);
}
And then call it like this:
txtArabicDate.setText(getFomattedDateByLocale(new Date(), AR_Format));
txtEnglishDate.setText(getFomattedDateByLocale(new Date(), EN_Format));
Don't forget to replace new Date() by your own date variable.
Good luck.
My way, with example: UTC iso format String to android User.
//string UTC instant to localDateTime
String example = "2022-01-27T13:04:23.891374801Z"
Instant instant = Instant.parse(example);
TimeZone timeZone = TimeZone.getDefault();
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, timeZone.toZoneId());
//localDateTime to device culture string output
DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);
String strDate = localDateTime.toLocalDate().format(dateFormatter);
DateTimeFormatter timeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);
String strTime = localDateTime.toLocalTime().format(timeFormatter);
//strings to views
txtDate.setText(strDate);
txtTime.setText(strTime);

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