I am trying to parse a date/time json from server side inside bind viewholder.
The date string am trying to parse is this:
2018-06-25T08:06:52Z
Here is the code that I am using ( got it from another stack overflow thread)
try {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH);
df.setTimeZone(TimeZone.getTimeZone("Africa/Nairobi"));
Date date = df.parse(timeToConvert);
df.setTimeZone(TimeZone.getDefault());
String formattedDate = df.format(date);
String trimmed = formattedDate.substring(11,16);
myViewHolder.date_TV.setText(trimmed);
}catch (Exception e){
}
However this does not work, the time set to the text view is the same as before parsing.
String timeToConvert = "2018-06-25T08:06:52Z";
Instant inst = Instant.parse(timeToConvert);
LocalTime time = inst.atZone(ZoneId.of("Africa/Nairobi"))
.toLocalTime()
.truncatedTo(ChronoUnit.MINUTES);
System.out.println("Time in Nairobi: " + time);
This prints:
Time in Nairobi: 11:06
I am using java.time, in this case the backport to Java 6 and 7. This backport is available in an Android edition too, which you may use for low Android API levels. My imports are:
import org.threeten.bp.Instant;
import org.threeten.bp.LocalTime;
import org.threeten.bp.ZoneId;
import org.threeten.bp.temporal.ChronoUnit;
If you need the time string for an API that requires this format, you’re fine. If you are after a time string for presentation to a user, consider using Java’s built-in format instead:
DateTimeFormatter timeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
ZonedDateTime dateTime = inst.atZone(ZoneId.of("Africa/Nairobi"));
System.out.println("Formatted: " + dateTime.format(timeFormatter));
I tried running this in Swahili (sw_KE) locale and got:
Formatted: 11:06 AM
Apparently this locale uses the English AM/PM way of notating times (I got the same result in Kikuyu and Kalenjin locales). In UK locale I get the same format as before:
Formatted: 11:06
I am using and suggesting java.time, the modern Java date and time API. For anyone reading along and using Java 8 or later or programming for Android API level 26 or higher, you don’t need the backport mentioned. Just import the built-in date-time classes from java.time with subpackages instead of the above mentioned ones.
What went wrong in your code?
Your error comes from hardcoding the Z in the date-time string as a literal. It’s a UTC offset of zero, and when you don’t parse it as such, the date-time string will be parsed in the time zone of your SimpleDateFormat, Africa/Nairobi, which is incorrect for your string.
IMHO you shouldn’t want to use SimpleDateFormat, TimeZone and Date at all, though. Those classes are long outdated and the first in particular has proven troublesome. I always use java.time instead.
Another tip: Don’t swallow exceptions. Don’t leave your catch block empty. Report the exception in some noticeable way. This is your chance to discover when something goes wrong in your code.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.timeto Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Wikipedia article: ISO 8601
The time set to the text view is the same as before parsing.
This is because you're not passing in a new SimpleDateFormat.
Try this:
final String serverDate = "2018-06-25T08:06:52Z"
final SimpleDateFormat serverDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
final SimpleDateFormat yourDateFormat = new SimpleDateFormat("yyyy-MM-dd"); // put whatever you want here!
try {
final Date date = serverDate.parse(serverDateFormat);
final String formattedDate = yourDateFormat.format(date);
} catch (ParseException e) {
System.out.println(e.toString());
}
This way you're interpreting the String with the server format into a pure Date object. You're then free to do what you wish with that object and turn it into whichever format you want (by providing your new format).
For more information on building your date format pattern, see this link.
Related
I have one time string format like yyyy-MM-dd'T'HH:mm:ss.SSSSSS with the time zone "GMT+05:30". I need to convert this format in yyyy-MM-dd'T'HH:mm:ss.SSS'Z' format with different time zone - "GMT0:00". I write below funtion to convert time string with different timezone. It works fine but can't change time.
public static String getUTCDate(String dateString) {
String oldDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS";
String newDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
String result = "";
SimpleDateFormat simpleDateFormatOld;
SimpleDateFormat simpleDateFormatNew;
try {
simpleDateFormatOld = new SimpleDateFormat(oldDateFormat,Locale.US);
simpleDateFormatNew = new SimpleDateFormat(newDateFormat,Locale.US);
simpleDateFormatNew.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
result = simpleDateFormatNew.format(simpleDateFormatOld.parse(dateString));
}
catch(Exception e) {
ExceptionHandler.handleException(e);
}
return result;
}
Example: I passed 2019-07-11T21:28:02.8469576 date time string. But in return I got 2019-07-11T21:28:02.846Z date time string without changing the time.
How can I update time of string?
Try this:
public static String getUTCDate(String dateString) {
String oldDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSS";
String newDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
String result = "";
SimpleDateFormat simpleDateFormatOld;
SimpleDateFormat simpleDateFormatNew;
try {
simpleDateFormatOld = new SimpleDateFormat();
simpleDateFormatOld.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
simpleDateFormatOld.applyPattern(oldDateFormat);
simpleDateFormatNew = new SimpleDateFormat(newDateFormat, Locale.US);
result = simpleDateFormatNew.format(simpleDateFormatOld.parse(dateString));
}
catch(Exception e) {
e.printStackTrace();
}
return result;
}
It worked for me. It just sets the timezone of the simpleDataFormatOld object before applying the date pattern to it.
For most purposes you should not want to convert a point in time from one string format in one time zone into a different string format in a different time zone. In your program keep your date and time in proper date-time objects, not strings (just like you wouldn’t keep an integer or floating-point value in a string). If you just need the point in time (not the original GMT offset, +05:30), the Instant class is the correct one to use. When your program accepts a string input, parse and convert it to Instant first thing and keep it as such. Only when you need to give string output, format the time back into a string and pass it out.
java.time and ThreeTenABP
Parse and convert input
ZoneId originalZone = ZoneId.of("Asia/Kolkata");
Instant time = LocalDateTime.parse("2019-07-11T21:28:02.8469576")
.atZone(originalZone)
.toInstant();
System.out.println(time);
The converted time prints as:
2019-07-11T15:58:02.846957600Z
For most purposes, don’t give time zone as a naked GMT offset. A named time zone better explains to the reader why this zone was chosen and is more future-proof in case the offset is changed (which happens more often than you would think). I am exploiting the fact that your string is in ISO 8601 format. In this case we don’t need to supply an explicit formatter. BTW your example string has 7 decimals on the seconds and your oldDateFormat seems to want 6. It doesn’t matter here since LocalDateTime.parse accepts anything from 0 through 9 decimals.
Format output
The output you asked for is a different variant of ISO 8601. The output above resembles pretty well because it too is ISO 8601, only there are too many decimals. So let’s apply an explicit formatting this time:
ZoneOffset newOffset = ZoneOffset.UTC;
DateTimeFormatter newFormatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral('T')
.appendPattern("HH:mm:ss.SSSX")
.toFormatter();
String formattedUtcDateTime = time.atOffset(newOffset).format(newFormatter);
System.out.println(formattedUtcDateTime);
2019-07-11T15:58:02.846Z
We see that java.time, the modern Java date and time API, forces us to specify the time zone offset, so forgetting to do so (like it seems you did in the code in the question, causing the unexpected output) simply is not possible.
I recommend against SimpleDateFormat and TimeZone
The date-time classes that you tried to use, SimpleDateFormat and TimeZone, are poorly designed and long outdated, the former in particular notoriously troublesome. Also there is no way that SimpleDateFormat can parse 6 or 7 decimals on the seconds correctly; it supports only milliseconds, exactly three decimals. Instead I am using java.time, the modern Java date and time API. I find it so much nicer to work with.
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Wikipedia article: ISO 8601
EDIT: Try this method:
public static String getUTCDate(String dateString) {
Log.d(TAG,"input : "+dateString);
String oldDateFormat = "yyyy-MM-dd'T'HH:mm:ss";
String newDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
String result = "";
SimpleDateFormat simpleDateFormatOld;
SimpleDateFormat simpleDateFormatNew;
try {
simpleDateFormatOld = new SimpleDateFormat(oldDateFormat, Locale.US);
simpleDateFormatNew = new SimpleDateFormat(newDateFormat,Locale.US);
simpleDateFormatOld.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
simpleDateFormatNew.setTimeZone(TimeZone.getTimeZone("GMT0:00"));
result = simpleDateFormatNew.format(simpleDateFormatOld.parse(dateString));
}
catch(Exception e) {
ExceptionHandler.handleException(e);
}
return result;
}
There are 2 changes:
1. Set time zone for New format also.
simpleDateFormatNew.setTimeZone(TimeZone.getTimeZone("GMT0:00"));
Remove milliseconds pattern from oldDateFormat.
String oldDateFormat = "yyyy-MM-dd'T'HH:mm:ss";
I have solved this issue by adding time zone for oldDateFormat also.
For example:
simpleDateFormatOld.setTimeZone(TimeZone.getTimeZone("GMT+5:30"));
simpleDateFormatNew.setTimeZone(TimeZone.getTimeZone("GMT+0:00"));
This is my code:
try {
Locale loc = new Locale("", countryCode);
DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, loc);
String pattern = ((SimpleDateFormat) formatter).toPattern();
format = pattern;
if (!format.contains("yyyy"))
format = format.replace("y", "yyyy");
} catch (Exception e) {
Log.e("date", "Error trying to get date from Locale:" + e.getMessage());
}
Now I do set the locale based on the country code.
It does get me back for "us" the displayCountryName as "United Stated" So I know the locale is correct.
But the locale returns "dd/MM/y" Why?
Edit
I need to have my minimum API set to 22. so I cannot use Java8 function:
DateTimeFormatter.ofLocalizedDate(dateStyle);
Because it asks for minimum 26
Also, I need the localised date format based on the country code I sent.
I have a list of countries, the user selects one and I need to show it's time and date format
To put more context, I load a list with this:
private void createCountriesHashmap() {
for (String iso : Locale.getISOCountries()) {
Locale l = new Locale("", iso);
map.put(l.getDisplayCountry(), iso);
if (l.getDisplayCountry().trim().length() > 0 && !countries.contains(l.getDisplayCountry())) {
countries.add(l.getDisplayCountry());
}
}
Collections.sort(countries);
}
When I select a object from there, I get its country code. I use the country code to create a locale: Locale loc = new Locale("", countryCode);
I need the date format of that country. Not my country
It’s not really clear whether a localized date format is rather tied to language or to country. It seems to me to be most often tied to language or to a combination of both. So when you are asking for a short date format for a locale without language (a country only), you will very often get y-MM-dd, which is the worldwide default short date format.
My Java 11 has 6 (six) available locales for the United States, and they tend to give different short date formats:
lkt_US (Lakota, a Sioux language) gives y-MM-dd (the worldwide default)
es_US (Spanish) and haw_US (Hawaiian) give d/M/yy
en_US_POSIX, en_US and chr_US (Cherokee) give M/d/yy
So I suppose all of the above would be correct answers for a short US date format. And I trust that the code in your own answer will give you one of them. The real question is which one of them you want. Or your user.
java.time and ThreeTenABP
Now that I am writing an answer, I want to mention that DateFormat and SimpleDateFormat are notoriously troublesome and long outdated. Instead consider using DateTimeFormatter and/or DateTimeFormatterBuilder from java.time, the modern Java date and time API.
Locale usSpanish = Locale.forLanguageTag("es-US");
String dateFormatPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.SHORT, null, IsoChronology.INSTANCE, usSpanish);
System.out.println("Format pattern: " + dateFormatPattern);
Format pattern: M/d/yy
I’ve run this snippet on Java 7 using ThreeTen Backport, the backport of java.time. And the format pattern isn’t the same as the one I got from Java 11 above. Java 7 is using Java’s built-in locale data, while Java 11 uses CLDR, Unicode Common Locale Data Repository. There are differences between the two. I don’t know what Android uses, but I trust that it’s something sensible.
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Java Specification Request (JSR) 310, where java.time was first described.
ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
CLDR - Unicode Common Locale Data Repository
Thanks to the comment from #MenoHochschild. I did manage to make it work like this:
Locale loc = new Locale("", countryCode);
Locale[] locales = java.text.DateFormat.getAvailableLocales();
for (Locale locale : locales) {
if (locale.getCountry().contains(countryCode)) {
loc = locale;
break;
}
}
DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, loc);
String pattern = ((SimpleDateFormat) formatter).toPattern();
I had the same problem, I solved with this (Is kotlin but you can easily convert it to java):
private val calendario: Calendar = Calendar.getInstance()
private val sdf: DateFormat = SimpleDateFormat.getDateInstance(DateFormat.SHORT)
fechaPagoBT.text = sdf.format(calendario.time)
It returns dd/MM/yyyy or MM/dd/yyyy based on the device region.
I recently started coding my really first Android project using Android Studio 3.1.2 and SDK 19.
One of my Objects has Date attributes. At some points I want to display the whole date time or parts of it in a TextView. So I tried it the rookie way and called toString() on my Date.
However the displayed text contains elements I didn't define in the SingleDateFormat pattern I used to create the Date Object.
This is how I create the Date on myObject:
Date date1;
Date date2;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
date1 = format.parse(json.getString("date_1"));
dtae2 = format.parse(json.getString("date_2"));
} catch(ParseException e) {
//error handling stuff
e.printStackTrace();
}
This is where I want to display the Date on a View:
myTextView.setText("First appearance logged at " + myObject.getDate1().toString());
I expected a String like 2018-08-16 12:14:42 to be displayed. Instead what I get is Thu Aug 12:14:42 GMT +02:00 2018. This seems to be another DateFormat and ignoring my custom pattern.
So my question is, if there's a way to manipulate the output of toString(), so the Date gets displayed in the way I defined in the pattern. Can I somehow pass the pattern to the toString() method?
EDIT
I changed the attributes of my Objects to String type, though it's way easier for presenting. The reason to convert them into a Date is, that I need to calculate the duration between the two guys, but that's not a problem i can't solve. Thanks to the community.
According to your need, you can just use json.getString("date_1").
You don't need to set extra logics. Parsing is needed when you want to convert String date to Date object for some calculation.
If you want to change format of received date then use this method.
changeStringDateFormat(json.getString("date_1"), "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd");
Just put this method inside your Util.
public String changeStringDateFormat(String date, String inputDateFormat, String outPutDateFormat) {
Date initDate = null;
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(inputDateFormat);
initDate = simpleDateFormat.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
SimpleDateFormat outputFormatter = new SimpleDateFormat(outPutDateFormat);
String parsedDate = outputFormatter.format(initDate);
return parsedDate;
}
See Java Date Doc, It returns string from default format.
public String toString()
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
Simply Write this code snippet
JAVA FILE
public class MainActivity extends AppCompatActivity {
TextView my_text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
my_text = findViewById(R.id.my_text);
String pattern = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
String date = simpleDateFormat.format(new Date());
Toast.makeText(getApplicationContext(), "" + date, Toast.LENGTH_SHORT).show();
my_text.setText("Your Date is : " + date);
}
}
XML FILE
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="mydemo.com.anew.MainActivity">
<TextView
android:id="#+id/my_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
See output:
See Screenshot of output same like your requirement get a current date:
Refer this Tutorial
Hope this may help to you
tl;dr
Use the modern java.time classes instead of the terrible legacy Date & SimpleDateFormat classes.
myJavaUtilDate // Never use `java.util.Date`.
.toInstant() // Convert from legacy class to modern replacement. Returns a `Instant` object, a moment in UTC.
.atOffset( // Convert from the basic `Instant` class to the more flexible `OffsetDateTime` class.
ZoneOffset.UTC // Constant defining an offset-from-UTC of zero, UTC itself.
) // Returns a `OffsetDateTime` object.
.format( // Generate a `String` with text representing the value of this `OffsetDateTime` object.
DateTimeFormatter.ISO_LOCAL_DATE_TIME // Pre-defined formatter stored in this constant.
) // Returns a `String` object.
.replace( "T" , " " ) // Replace the standard `T` in the middle with your desired SPACE character.
2018-08-16 10:14:42
java.time
You are using terrible old classes that were supplanted years ago by the java.time classes.
If handed a java.util.Date object, immediately convert to java.time.Instant. Both represent a moment in UTC. Instant has a finer resolution of nanoseconds rather than milliseconds.
To convert between the legacy and modern classes, look to new conversion methods added to the old classes.
Instant
Instant instant = myJavaUtilDate.toInstant() ; // New method on old class for converting to/from java.time classes.
ISO 8601
To generate a String with text in standard ISO 8601 format similar to your desired format, call toString.
String output = instant.toString() ; // Generate text in standard ISO 8601 format.
Elapsed time = Duration
By the way, to calculate elapsed time, use the Duration classes. Pass a pair of Instant objects to calculate the number of 24-hour "days", hours, minutes, and seconds elapsed.
Duration d = Duration.between( start , stop ) ; // Calc elapsed time.
2018-08-16T10:14:42Z
OffsetDateTime
For other formatting, convert from the basic Instant class to the more flexible OffsetDateTime class.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
odt.toString(): 2018-08-16T10:14:42Z
DateTimeFormatter
Your desired format is close to the predefined formatter DateTimeFormatter.ISO_LOCAL_DATE_TIME. Just replace the T in the middle with a SPACE.
String output = odt.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " ) ;
2018-08-16 10:14:42
ZonedDateTime
Keep in mind that we are only looking at UTC so far. For any given moment, the date and the time-of-day both vary around the globe by zone.
If you want to see that same moment through the lens of the wall-clock time used by the people of a certain region (a time zone), then apply a ZoneId to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
zdt.toString(): 2018-08-16T11:14:42+01:00[Africa/Tunis]
You can use the same formatter as seen above to generate a string in your desired format.
String output = zdt.format( f ) ;
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.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
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
Much 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.
You need to use SimpleDateFormat something like this:
String myFormat = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
myTextView.setText("First appearance logged at " + sdf.format(date1));
In my project I've been formatting using the format() function, like so:
myTextView.setText("First appearance logged at " + format.format(myObject.getData1()));
I hope that helps.
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.
I want to get the current time on the device in the format: 2013-10-17 15:45:01 ?
The server sends me the date of an object in the format above as a string. Now i want to get the phones current time and then check if there is a difference of say more than 5 minutes?
So A: How can i get the devices current time in this fomat: 2013-10-17 15:45:01
B how can I work out the difference between the two.
You can use SimpleDateFormat to specify the pattern you want:
new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new java.util.Date())
However, if you just want to know whether the time difference is within a certain threshold, you should probably just compare long values. If your threshold is 5 minutes, then this is 5 * 60 * 1000 milliseconds so you can use the same SimpleDateFormat by calling it's parse method and check the long values.
Example:
new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse("2013-10-13 14:54:03").getTime()
Date currentDate = new Date(); will initialize a new date with the current time. In addition, convert the server provided time and take the difference.
String objectCreatedDateString = "2013-10-17 15:45:01";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date objectCreatedDate = null;
Date currentDate = new Date();
try
{objectCreatedDate = format.parse(objectCreatedDateString);}
catch (ParseException e)
{Log.e(TAG, e.getMessage());}
int timeDifferential;
if (objectCreatedDate != null)
timeDifferential = objectCreatedDate.getMinutes() - currentDate.getMinutes();
tl;dr
Duration.between( // Calculate time elapsed between two moments.
LocalDateTime // Represent a date with time-of-day but lacking the context of a time zone or offset-from-UTC.
.parse( "2013-10-17 15:45:01".replace( " " , "T" ) )
.atOffset( ZoneOffset.UTC ) // Returns an `OffsetDateTime` object.
.toInstant() , // Returns an `Instant` object.
Instant.now() // Capture the current moment as seen in UTC.
)
.toMinutes()
> 5
java.time
The other Answers are outdated, using terrible classes that were years ago supplanted by the modern java.time classes defined in JSR 310.
Parse your incoming string.
String input = "2013-10-17 15:45:01" ;
Modify the input to comply with ISO 8601. I suggest you educate the publisher of your data about the ISO 8601 standard.
String inoutModified = input.replace( " " , "T" ) ;
Parse as a LocalDateTime because this input lacks an indicator of the intended offset or time zone.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
I assume that input was intended to represent a moment as seen in UTC, with an offset of zero hours minutes seconds. If so, educate the publisher of your data about appending a Z on the end to so indicate, per ISO 8601.
OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
Extract an object of the simpler class, Instant. This class is always in UTC.
Instant then = odt.toInstant() ;
Get current moment as seen in UTC.
Instant now = Instant.now() ;
Calculate the difference.
Duration d = Duration.between( then , now ) ;
Get duration as total whole minutes.
long minutes = d.toMinutes() ;
Test.
if ( minutes > 5 ) { … }
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. Hibernate 5 & JPA 2.2 support java.time.
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 brought 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 (26+) bundle implementations of the java.time classes.
For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
Use SimpleDateFromat Class
DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
dateFormatter.format(date);
Also check this documentation
If you can ask the server to send you an RFC3339 compliant date/time string, then Here is a simple answer to both of your questions:
public String getClientTime() {
Time clientTime = new Time().setToNow();
return clientTime.format("%Y-%m-%d %H:%M:%S");
}
public int diffClientAndServerTime(String svrTimeStr) {
Time svrTime = new Time();
svrTime.parse3339(svrTimeStr);
Time clientTime = new Time();
clientTime.setToNow();
return svrTime.compare( svrTime, clientTime);
}