I have an app that displays dates and times in a localized format for different areas, that is - it shows a user dates and times based on his preference. But my issue is that it always displays numbers, ie yyyy.mm.dd, or mm/dd/yyy, or dd,mm,yyyy. What I would like to have is this: show date so that the day is a number, year is a number, but the month is displayed as a string, ie. Jan / Xin / Gen / Jān / Yan... or 01 Jan 2018 / Jan 01 2018 / 2018 Jan 01, and so on, but still keep the current local formatting. I know that I could do that if I hardcode it like MMM, but I want it to change, depending on the localized format.
So basically this is my question: how can I display localized time, from a value I get from the server (yyyy-MM-dd HH: mm: ss), with month displayed as a three letter word, no matter what locale it uses?
I know this question sounds familiar, but so far I have tried a lot of answers, both on stack overflow, and other sources, but without any success. Some of the things I have tried include: 1 / 2 / 3 / 4 / 5 / 6 ... but I couldn't make it work in my example.
My Adapter:
public void onBindViewHolder(RestaurantsAdapter.RestaurantsViewHolder holder, int position) {
// getting restaurant data for the row
Restaurant restaurant = restaurant Items.get(position);
holder.userName.setText(restaurant .getUserName());
holder.date.setText(convertDate(restaurant .getDateTime())); //string dobiti u formatu, pretvoriti ga u localized i podijeliti na dva dijela
holder.time.setText(convertTime(restaurant .getDateTime()));
TextDrawable.IBuilder builder = TextDrawable.builder()
.beginConfig()
.withBorder(0)
.toUpperCase()
.endConfig()
.roundRect(10);
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(restaurant.getUserId());
TextDrawable textDrawable = builder.build(restaurant Items.get(position).getUserName().substring(0, 1), color);
holder.thumbNail.setImageDrawable(textDrawable);
Picasso.with(context)
.load(AppConfig.URL_PROFILE_PHOTO + restaurant.getThumbnailUrl())
.placeholder(textDrawable)
.error(textDrawable)
.transform(new RoundedTransform(12, 0))
.fit()
.centerCrop()
.into(holder.thumbNail);
}
private String convertDate(String time) {
final DateFormat shortDateFormat = android.text.format.DateFormat.getDateFormat(context.getApplicationContext());
SimpleDateFormat dateFormatReceived = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
SimpleDateFormat dateFormatConverted = new SimpleDateFormat(((SimpleDateFormat) shortDateFormat).toPattern(), Locale.getDefault());
java.util.Date date = null;
try {
date = dateFormatReceived.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
return dateFormatConverted.format(date);
}
private String convertTime(String time) {
final DateFormat shortTimeFormat = android.text.format.DateFormat.getTimeFormat(context.getApplicationContext());
SimpleDateFormat timeFormatReceived = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
SimpleDateFormat timeFormatConverted = new SimpleDateFormat(((SimpleDateFormat) shortTimeFormat).toPattern(), Locale.getDefault());
java.util.Date date = null;
try {
date = timeFormatReceived.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
return timeFormatConverted.format(date);
}
UPDATE:
I tried adding this to my solution:
private String convertDate(String time) {
final DateFormat shortDateFormat = android.text.format.DateFormat.getDateFormat(context.getApplicationContext());
Calendar Now = Calendar.getInstance();
Now.getDisplayName(Calendar.HOUR, Calendar.SHORT, Locale.getDefault());
SimpleDateFormat dateFormatReceived = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
SimpleDateFormat dateFormatConverted = new SimpleDateFormat(((SimpleDateFormat) shortDateFormat).toPattern(), Locale.getDefault());
dateFormatConverted.getDisplayName(Calendar.HOUR, Calendar.SHORT, Locale.getDefault());
java.util.Date date = null;
try {
date = dateFormatReceived.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
return dateFormatConverted.format(date);
}
I think the following method will give you the date-time formatter you want.
public static DateTimeFormatter getLocalizedDateFormatter(Locale requestedLocale) {
String formatPatternString = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
FormatStyle.SHORT, null,
Chronology.ofLocale(requestedLocale), requestedLocale);
// if not already showing month name, modify so it shows abbreviated month name
if (! formatPatternString.contains("MMM")) {
formatPatternString = formatPatternString.replaceAll("M+", "MMM");
}
return DateTimeFormatter.ofPattern(formatPatternString, requestedLocale);
}
Test:
Locale[] locales = { Locale.US, Locale.FRANCE, Locale.GERMANY,
Locale.forLanguageTag("da-DK"), Locale.forLanguageTag("sr-BA") };
LocalDate today = LocalDate.now(ZoneId.of("Europe/Sarajevo"));
for (Locale currentLocale : locales) {
DateTimeFormatter ldf = getLocalizedDateFormatter(currentLocale);
System.out.format(currentLocale, "%-33S%s%n",
currentLocale.getDisplayName(), today.format(ldf));
}
Output:
ENGLISH (UNITED STATES) Dec/24/17
FRENCH (FRANCE) 24/déc./17
GERMAN (GERMANY) 24.Dez.17
DANSK (DANMARK) 24-dec.-17
SERBIAN (BOSNIA AND HERZEGOVINA) 17-дец-24
JSR-310 also known as java.time
You tried to use the long outdated and notoriously troublesome classes DateFormat and SimpleDateFormat. Instead I recommend you make it a habit to use JSR-310, the modern Java date and time API. So I do that in the method above.
I don’t think it was part of the question, but for the sake of completeness, parse the date-time string as follows. The formatter you get from my getLocalizedDateFormatter can be used for formatting a LocalDateTime and many other date-time types in addition to LocalDate.
LocalDateTime ldt = LocalDateTime.parse("2017-12-24 22:51:34",
DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss"));
String formattedDate = ldt.format(getLocalizedDateFormatter(Locale.UK));
Question: Can I use JSR-310 on Android?
Yes you can. It just requires at least Java 6.
In Java 8 and later the new API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310).
On Android, use the Android edition of ThreeTen Backport. It’s called ThreeTenABP.
In the latter two cases, make sure to add the appropriate edition of the backport library to your project, use the links below, and to import the classes I use from org.threeten.bp and org.threeten.bp.format.
Links
Oracle tutorial: Date Time, explaining how to use java.time.
ThreeTen Backport project
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Java Specification Request (JSR) 310, where the modern date and time API was first described.
Please try to use
getDisplayName(...) method
In order to get more information you had better go through this documentation
Editted
More sufficiently you can try this way:
int monthOfYear = Calendar.JULY; // 6
String monthName = new
DateFormatSymbols(Locale.getDefault()).getShortMonths()[monthOfYear];
Related
I am having a method which formats my particular data string
public static String dateFormatter(String dateToFormat){
SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd", Locale.UK);
// All the fields in dateFormatter must be in dateParser
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy, MMM d, EEE", Locale.UK);
Date date = new Date();
try {
date = dateParser.parse(dateToFormat);
} catch (ParseException e) {
e.printStackTrace();
}
assert date != null;
return dateFormatter.format(date);
}
The issue am having is that the String date am parsing as dateToFormat can be in the following date format pattern
2021-03-02 which will use date format pattern of "yyyy-MM-dd" in dateParser
2021-03-02 20:16 which will use date format pattern of "yyyy-MM-dd HH:mm" in dateParser
2021-03-02 20:16:28 which will use date format pattern of "yyyy-MM-dd HH:mm:ss" in dateParser
I would like the dateParser to be assigned with an if statement instead of me going back to the code
everytime to change so that the dateParser uses a particular format according to the date parsed for example
SimpleDateFormat dateParser;
if ("yyyy-MM-dd"){
dateParser = new SimpleDateFormat("yyyy-MM-dd", Locale.UK);
}else if ("yyyy-MM-dd HH:mm") {
dateParser = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.UK);
}else if ("yyyy-MM-dd HH:mm:ss") {
dateParser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.UK);
}
Where "yyyy-MM-dd" and "yyyy-MM-dd HH:mm" is the format pattern of the parsed String dateToFormat
Create 3 defferent formatter for yyyy-MM-dd, yyyy-MM-dd HH:mm, yyyy-MM-dd HH:mm:ss respectively formatter1, formatter2, formatter3
private String dateFormatter(String dateToFormat) {
Date date = null;
SimpleDateFormat formatter1=new SimpleDateFormat("yyyy-MM-dd", Locale.UK);
SimpleDateFormat formatter2=new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.UK);
SimpleDateFormat formatter3=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.UK);
try {
try {
date = formatter1.parse(dateToFormat);
} catch (
Exception exp) {
try {
date = formatter2.parse(dateToFormat);
} catch (Exception exp2) {
try {
date = formatter3.parse(dateToFormat);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy, MMM d, EEE", Locale.UK);
return dateFormatter.format(date);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
java.time and optional parts of the format pattern
Consider using java.time, the modern Java date and time API, for your date work. The following method does it. Since with java.time there is no reason to create the formatters anew for each call, I have placed them outside the method.
private static final DateTimeFormatter inputParser
= DateTimeFormatter.ofPattern("uuuu-MM-dd[ HH:mm[:ss]]");
private static final DateTimeFormatter outputFormatter
= DateTimeFormatter.ofPattern("uuuu, MMM d, EEE", Locale.UK);
public static String dateFormatter(String dateToFormat){
LocalDate date = LocalDate.parse(dateToFormat, inputParser);
return date.format(outputFormatter);
}
Try it out:
System.out.println("2021-03-02 -> " + dateFormatter("2021-03-02"));
System.out.println("2021-03-02 20:16 -> " + dateFormatter("2021-03-02 20:16"));
System.out.println("2021-03-02 20:16:28 -> " + dateFormatter("2021-03-02 20:16:28"));
Output is:
2021-03-02 -> 2021, Mar 2, Tue
2021-03-02 20:16 -> 2021, Mar 2, Tue
2021-03-02 20:16:28 -> 2021, Mar 2, Tue
The square brackets in the format pattern string for the input parser denote optional parts. So the time of day is allowed to be there or not. And if it’s there, the seconds are allowed to be present or absent.
This said, you should not want to process your date and time as strings in your app. Process a LocalDate, or if there’s any possibility that you will need the time of day, then for example a ZonedDateTime. When you get string input, parse it first thing. And only format back into a string when you must give string output.
With if statements
can your find a way that i can use SimpleDateFormat
I would not want to do that. The SimpleDateFormat class is a notorious troublemaker of a class and fortunately long outdated
I there a way i can only use if statements so that i don't get to use
many SimpleDateFormats
It doesn’t get you fewer formatters, but you may use if statements. Just select by the length of the string;
public static String dateFormatter(String dateToFormat){
LocalDate date;
if (dateToFormat.length() == 10) { // uuuu-MM-dd
date = LocalDate.parse(dateToFormat, dateParser);
} else if (dateToFormat.length() == 16) { // uuuu-MM-dd HH:mm
date = LocalDate.parse(dateToFormat, dateTimeNoSecsParser);
} else if (dateToFormat.length() == 19) { // uuuu-MM-dd HH:mm:ss
date = LocalDate.parse(dateToFormat, dateTimeWithSecsParser);
} else {
throw new IllegalArgumentException("Unsupported length " + dateToFormat.length());
}
return date.format(outputFormatter);
}
Only now we need to declare four formatters, three for parsing and one for formatting. I am leaving constructing the parsers to yourself.
I guess that the same if-else strucure will work with SimpleDateFormat too. You may even just select the format pattern string from the length of the input string and only construct one SimpleDateFormat instance in each call of the method. I repeat: I would not myself use SimpleDateformat.
Question: Doesn’t java.time require Android API level 26?
Call requires API level 26 (current min is 16):
java.time.format.DateTimeFormatter#ofPattern
Edit: Contrary to what you might think from this error message java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On older Android 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.
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.
This question already has answers here:
Converting ISO 8601-compliant String to java.util.Date
(31 answers)
Closed 4 years ago.
How do I can parse this date 2018-01-09T11:11:02.0+03:00 to dd.MM.yyyy hh:mm format in Android?
And what does T between 09 and 11 mean?
Thanks.
I don't know how the back-end developer got this format.
I am using Java.
You can do this with SimpleDateFormat.
Here is a tested example in Java:
String dateString = "2018-01-09T11:11:02.0+03:00";
String inPattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
String outPattern = "dd.MM.yyyy hh:mm";
SimpleDateFormat inFormat = new SimpleDateFormat(inPattern, Locale.getDefault());
SimpleDateFormat outFormat = new SimpleDateFormat(outPattern, Locale.getDefault());
try {
Date inDate = inFormat.parse(dateString);
String outDate = outFormat.format(inDate);
Log.e("TEST", outDate);
} catch (ParseException e) {
e.printStackTrace();
}
Here is a tested example in Kotlin:
val dateString = "2018-01-09T11:11:02.0+03:00"
val inPattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"
val outPattern = "dd.MM.yyyy hh:mm"
val inFormat = SimpleDateFormat(inPattern, Locale.getDefault())
val outFormat = SimpleDateFormat(outPattern, Locale.getDefault())
val inDate = inFormat.parse(dateString)
val outDate = outFormat.format(inDate)
Log.e("TEST", outDate)
If you are using java, you can use SimpeDateFormat with patterns:
String date = "2018-01-09T11:11:02.0+03:00";
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
SimpleDateFormat output = new SimpleDateFormat("dd.MM.yyyy hh:mm");
Date d = null;
try {
d = dateformat.parse(date /*your date as String*/);
} catch (ParseException e) {
e.printStackTrace();
}
String formattedDate = output.format(d);
Log.d("Date format", "output date :" + formattedDate);
The output is :
D/Date format: output date :09.01.2018 09:11
EDIT : Thanks to #OleV.V., for API > 26, or using ThreeTenABP we can use
DateTimeFormatter, we can do something like that
String date = "2018-01-09T11:11:02.0+03:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
DateTimeFormatter formatterOut = DateTimeFormatter.ofPattern("dd.MM.yyyy hh:mm");
LocalDate parsedDate = LocalDate.parse(date, formatter);
String formattedDate = formatterOut.format(parsedDate);
Log.d("Date format", "output date :" + formattedDate);
DateTimeFormatter desiredFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
String backendDateTimeString = "2018-01-09T11:11:02.0+03:00";
OffsetDateTime dateTime = OffsetDateTime.parse(backendDateTimeString);
String presentationDateTimeString = dateTime.format(desiredFormatter);
System.out.println(presentationDateTimeString);
This prints:
09.01.2018 11:11
Please note: I am using uppercase HH in the format pattern string. This indicates hour of day from 00 through 23. In the question you used lowercase hh, which in a format pattern string means hour with AM or PM from 01 through 12, so 00:33 would come out as 12:33 and 15:47 as 03:47. I didn’t think you intended this.
The format that your backend developer got, 2018-01-09T11:11:02.0+03:00, is ISO 8601. It’s widespread, and it’s the international standard, so it’s good that s/he got that. The funny T in the middle indicates the start of the time part to separate it from the date part. The one-arg OffsetDateTime.parse method parses ISO 8601, which is why we didn’t need any formatter for parsing. OffsetDateTime and DateTimeFormatter are classes from java.time, the modern Java date and time API.
Question: Can I use java.time on Android?
Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (API level 26 and up) 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 (my code was tested with these imports).
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
I am trying to format a JSON which has a date key in the format:
date: "2017-05-23T06:25:50"
My current attempt is the following:
private String formatDate(String date) {
SimpleDateFormat format = new SimpleDateFormat("MM/DD/yyyy");
String formattedDate = "";
try {
formattedDate = format.format(format.parse(String.valueOf(date)));
} catch (ParseException e) {
e.printStackTrace();
}
return formattedDate;
}
But in this occasion, the result isn't shown in my app, the TextView is invisible and I couldn't log anything.
I really tried other solutions, but no success for me. I don't know if it's because the incoming value is a string.
Use this code to format your `2017-05-23T06:25:50'
String strDate = "2017-05-23T06:25:50";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date convertedDate = new Date();
try {
convertedDate = dateFormat.parse(strDate);
SimpleDateFormat sdfnewformat = new SimpleDateFormat("MMM dd yyyy");
String finalDateString = sdfnewformat.format(convertedDate);
} catch (ParseException e) {
e.printStackTrace();
}
The converted finalDateString set to your textView
This will work for you.
String oldstring= "2017-05-23T06:25:50.0";
Date datee = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(oldstring);
This code worked for me :
public static String getNewsDetailsDateTime(String dateTime) {
#SuppressLint("SimpleDateFormat") DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
Date date = null;
try {
date = format.parse(dateTime);
} catch (ParseException e) {
e.printStackTrace();
}
#SuppressLint("SimpleDateFormat") String strPublishDateTime = new SimpleDateFormat("MMM d, yyyy h:mm a").format(date);
return strPublishDateTime;
}
Out put format was : Dec 20 , 2017 2.30 pm.
Use this function :
private String convertDate(String dt) {
//String date="2017-05-23T06:25:50";
try {
SimpleDateFormat spf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); //date format in which your current string is
Date newDate = null;
newDate = spf.parse(dt);
spf = new SimpleDateFormat("MM/DD/yyyy"); //date format in which you want to convert
dt = spf.format(newDate);
System.out.println(dt);
Log.e("FRM_DT", dt);
} catch (ParseException e) {
e.printStackTrace();
}
return dt;
}
TL;DR
private static final DateTimeFormatter DATE_FORMATTER
= DateTimeFormatter.ofPattern("MM/dd/uuuu");
private static String formatDate(String date) {
return LocalDateTime.parse(date).format(DATE_FORMATTER);
}
Now formatDate("2017-05-23T06:25:50") returns the desired string of 05/23/2017.
java.time
In 2017 I see no reason why you should struggle with the long outdated and notoriously troublesome SimpleDateFormat class. java.time, the modern Java date and time API also known as JSR-310, is so much nicer to work with.
Often when converting from one date-time format to another you need two formatters, one for parsing the input format and one for formatting into the output format. Not here. This is because your string like 2017-05-23T06:25:50 is in the ISO 8601 format, the standard that the modern classes parse as their default, that is, without an explicit formatter. So we only need one formatter, for formatting.
What went wrong in your code
When I run your code, I get a ParseException: Unparseable date: "2017-05-23T06:25:50". If you didn’t notice the exception already, then you have a serious flaw in your project setup that hides vital information about errors from you. Please fix first thing.
A ParseException has a method getErrorOffset (a bit overlooked), which in this case returns 4. Offset 4 in your string is where the first hyphen is. So when parsing in the format MM/DD/yyyy, your SimpleDateFormat accepted 2017 as a month (funny, isn’t it?), then expected a slash and got a hyphen instead, and therefore threw the exception.
You’ve got another error in your format pattern string: Uppercase DD is for day-of-year (143 in this example). Lowercase dd should be used for day-of-month.
Question: Can I use java.time on Android?
Yes you can. It just requires at least Java 6.
In Java 8 and later the new API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310).
On Android, use the Android edition of ThreeTen Backport. It’s called ThreeTenABP.
Links
Oracle tutorial: Date Time, explaining how to use java.time.
ThreeTen Backport project
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Java Specification Request (JSR) 310, where the modern date and time API was first described.
Try this:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Calendar c = Calendar.getInstance();
try {
c.setTime(sdf.parse(dt));
} catch (ParseException e) {
e.printStackTrace();
}
SimpleDateFormat sdf1 = new SimpleDateFormat("dd/MM/yyyy");
String output = sdf1.format(c.getTime());
I am trying to use the Android SimpleDateFormat like this:
String _Date = "2010-09-29 08:45:22"
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = fmt.parse(_Date);
return fmt.format(date);
}
catch(ParseException pe) {
return "Date";
}
The result is good and I have: 2010-09-29
But if I change the SimpleDateFormat to
SimpleDateFormat("dd-MM-yyyy");
the problem is that I will got 03-03-0035 !!!!
Why and how to get the format like dd-MM-yyyy?
I assume you would like to reverse the date format?
SimpleDateFormat can be used for parsing and formatting.
You just need two formats, one that parses the string and the other that returns the desired print out:
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
Date date = fmt.parse(dateString);
SimpleDateFormat fmtOut = new SimpleDateFormat("dd-MM-yyyy");
return fmtOut.format(date);
Since Java 8:
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd").withZone(ZoneOffset.UTC);
TemporalAccessor date = fmt.parse(dateString);
Instant time = Instant.from(date);
DateTimeFormatter fmtOut = DateTimeFormatter.ofPattern("dd-MM-yyyy").withZone(ZoneOffset.UTC);
return fmtOut.format(time);
Below is all date formats available, read more doc here.
Symbol Meaning Kind Example
D day in year Number 189
E day of week Text E/EE/EEE:Tue, EEEE:Tuesday, EEEEE:T
F day of week in month Number 2 (2nd Wed in July)
G era designator Text AD
H hour in day (0-23) Number 0
K hour in am/pm (0-11) Number 0
L stand-alone month Text L:1 LL:01 LLL:Jan LLLL:January LLLLL:J
M month in year Text M:1 MM:01 MMM:Jan MMMM:January MMMMM:J
S fractional seconds Number 978
W week in month Number 2
Z time zone (RFC 822) Time Zone Z/ZZ/ZZZ:-0800 ZZZZ:GMT-08:00 ZZZZZ:-08:00
a am/pm marker Text PM
c stand-alone day of week Text c/cc/ccc:Tue, cccc:Tuesday, ccccc:T
d day in month Number 10
h hour in am/pm (1-12) Number 12
k hour in day (1-24) Number 24
m minute in hour Number 30
s second in minute Number 55
w week in year Number 27
G era designator Text AD
y year Number yy:10 y/yyy/yyyy:2010
z time zone Time Zone z/zz/zzz:PST zzzz:Pacific Standard
I think this Link might helps you
OR
Date date = Calendar.getInstance().getTime();
//
// Display a date in day, month, year format
//
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
String today = formatter.format(date);
System.out.println("Today : " + today);
String _Date = "2010-09-29 08:45:22"
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat fmt2 = new SimpleDateFormat("dd-MM-yyyy");
try {
Date date = fmt.parse(_Date);
return fmt2.format(date);
}
catch(ParseException pe) {
return "Date";
}
try this.
Using the date-time API of java.util and their formatting API, SimpleDateFormat I have come across surprises several times but this is the biggest one! 😮😮😮
Given below is the illustration of what you have described in your question:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
class Main {
public static void main(String[] args) {
System.out.println(formatDateWithPattern1("2010-09-29 08:45:22"));
System.out.println(formatDateWithPattern2("2010-09-29 08:45:22"));
}
static String formatDateWithPattern1(String strDate) {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = fmt.parse(strDate);
return fmt.format(date);
} catch (ParseException pe) {
return "Date";
}
}
static String formatDateWithPattern2(String strDate) {
SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy");
try {
Date date = fmt.parse(strDate);
return fmt.format(date);
} catch (ParseException pe) {
return "Date";
}
}
}
Output:
2010-09-29
03-03-0035
Surprisingly, SimpleDateFormat silently performed the parsing and formatting without raising an alarm. Anyone reading this will not have a second thought 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:
Since the pattern used in both the functions are wrong as per the input string, the parser should raise the alarm and the parsing/formatting types of the modern date-time API do it responsibly.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
class Main {
public static void main(String[] args) {
System.out.println(formatDateWithPattern1("2010-09-29 08:45:22"));
System.out.println(formatDateWithPattern2("2010-09-29 08:45:22"));
}
static String formatDateWithPattern1(String strDate) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd");
try {
LocalDateTime date = LocalDateTime.parse(strDate, dtf);
return dtf.format(date);
} catch (DateTimeParseException dtpe) {
return "Date";
}
}
static String formatDateWithPattern2(String strDate) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-uuuu");
try {
LocalDateTime date = LocalDateTime.parse(strDate, dtf);
return dtf.format(date);
} catch (DateTimeParseException dtpe) {
return "Date";
}
}
}
Output:
Date
Date
Moral of the story
The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. Stop using them completely and switch to the modern date-time API. Learn about the modern date-time API at Trail: Date Time.
Stick to the format in your input date-time string while parsing it. If you want the output in a different format, use a differnt instance of the parser/formatter class.
Demo:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
class Main {
public static void main(String[] args) {
String strDateTime = "2010-09-29 08:45:22";
DateTimeFormatter dtfForParsing = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtfForParsing);
System.out.println(ldt);// The default format as returned by LocalDateTime#toString
// Some custom formats for output
System.out.println("########In custom formats########");
DateTimeFormatter dtfForFormatting1 = DateTimeFormatter.ofPattern("dd-MM-uuuu HH:mm:ss");
DateTimeFormatter dtfForFormatting2 = DateTimeFormatter.ofPattern("dd-MM-uuuu");
DateTimeFormatter dtfForFormatting3 = DateTimeFormatter.ofPattern("'Day: 'EEEE, 'Date: 'MMMM dd uuuu");
System.out.println(dtfForFormatting1.format(ldt));
System.out.println(dtfForFormatting2.format(ldt));
System.out.println(dtfForFormatting3.format(ldt));
System.out.println("################################");
}
}
Output:
2010-09-29T08:45:22
########In custom formats########
29-09-2010 08:45:22
29-09-2010
Day: Wednesday, Date: September 29 2010
################################
This worked for me...
#SuppressLint("SimpleDateFormat")
private void setTheDate() {
long msTime = System.currentTimeMillis();
Date curDateTime = new Date(msTime);
SimpleDateFormat formatter = new SimpleDateFormat("MM'/'dd'/'y hh:mm");
curDate = formatter.format(curDateTime);
mDateText.setText("" + curDate);
}
java.time and desugaring
I recommend that you use java.time, the modern Java date and time API, for your date work. First define a formatter for your string:
private static DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
Then do:
String dateString = "2010-09-29 08:45:22";
LocalDateTime dateTime = LocalDateTime.parse(dateString, formatter);
String newString = dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println(newString);
Output is:
2010-09-29
I find it a good practice to parse the entire string even though we currently have no use for the time of day. That may come some other day. java.time furnishes a predefined formatter for your first output format, DateTimeFormatter.ISO_LOCAL_DATE. If you want the opposite order of day, month and year, we will need to write our own formatter for that:
private static DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("dd-MM-uuuu");
Then we can obtain that too:
String dmyReversed = dateTime.format(dateFormatter);
System.out.println(dmyReversed);
29-09-2010
What went wrong in your code?
the problem is that I will got 03-03-0035 !!!!
This is how confusing a SimpleDateFormat with standard settings is: With format pattern dd-MM-yyyy it parses 2010-09-29 as the 2010th day of month 9 of year 29. Year 29 AD that is. And it doesn’t disturb it that there aren’t 2010 days in September. It just keeps counting days through the following months and years and ends up five and a half years later, on 3 March year 35.
Which is just a little bit of the reason why I say: don’t use that class.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
On older Android 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.
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.
uuuu versus yyyy in DateTimeFormatter formatting pattern codes in Java?
Wikipedia article: ISO 8601
Here is an easy example of SimpleDateFormat tried in Android Studio 3 and Java 9:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
String strDate = sdf.format(strDate);
Note:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); shows
some deprecation warning in Android Studio 3 Lint. So, add a second
parameter Locale.US to specify the Localization in date formatting.
It took a lot of efforts. I did a lot of hit and trial and finally I got the solution. I had used ""MMM"" for showing month as: JAN
If you looking for date, month and year separately
or how to use letters from answer of heloisasim
SimpleDateFormat day = new SimpleDateFormat("d");
SimpleDateFormat month = new SimpleDateFormat("M");
SimpleDateFormat year = new SimpleDateFormat("y");
Date d = new Date();
String dayS = day.format(d);
String monthS = month.format(d);
String yearS = year.format(d);
public String formatDate(String dateString) {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = fmt.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
SimpleDateFormat fmtOut = new SimpleDateFormat("dd-MM-yyyy");
return fmtOut.format(date);
}
I have milliseconds.
I need it to be converted to date format of
example:
23/10/2011
How to achieve it?
Just Try this Sample code:-
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Test {
/**
* Main Method
*/
public static void main(String[] args) {
System.out.println(getDate(82233213123L, "dd/MM/yyyy hh:mm:ss.SSS"));
}
/**
* Return date in specified format.
* #param milliSeconds Date in milliseconds
* #param dateFormat Date format
* #return String representing date in specified format
*/
public static String getDate(long milliSeconds, String dateFormat)
{
// Create a DateFormatter object for displaying date in specified format.
SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
// Create a calendar object that will convert the date and time value in milliseconds to date.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(milliSeconds);
return formatter.format(calendar.getTime());
}
}
Convert the millisecond value to Date instance and pass it to the choosen formatter.
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
String dateString = formatter.format(new Date(dateInMillis)));
public static String convertDate(String dateInMilliseconds,String dateFormat) {
return DateFormat.format(dateFormat, Long.parseLong(dateInMilliseconds)).toString();
}
Call this function
convertDate("82233213123","dd/MM/yyyy hh:mm:ss");
tl;dr
Instant.ofEpochMilli( myMillisSinceEpoch ) // Convert count-of-milliseconds-since-epoch into a date-time in UTC (`Instant`).
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Adjust into the wall-clock time used by the people of a particular region (a time zone). Produces a `ZonedDateTime` object.
.toLocalDate() // Extract the date-only value (a `LocalDate` object) from the `ZonedDateTime` object, without time-of-day and without time zone.
.format( // Generate a string to textually represent the date value.
DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) // Specify a formatting pattern. Tip: Consider using `DateTimeFormatter.ofLocalized…` instead to soft-code the formatting pattern.
) // Returns a `String` object.
java.time
The modern approach uses the java.time classes that supplant the troublesome old legacy date-time classes used by all the other Answers.
Assuming you have a long number of milliseconds since the epoch reference of first moment of 1970 in UTC, 1970-01-01T00:00:00Z…
Instant instant = Instant.ofEpochMilli( myMillisSinceEpoch ) ;
To get a date requires a time zone. For any given moment, the date varies around the globe by zone.
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, different wall-clock time.
Extract a date-only value.
LocalDate ld = zdt.toLocalDate() ;
Generate a String representing that value using standard ISO 8601 format.
String output = ld.toString() ;
Generate a String in custom format.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ;
String output = ld.format( f ) ;
Tip: Consider letting java.time automatically localize for you rather than hard-code a formatting pattern. Use the DateTimeFormatter.ofLocalized… methods.
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), the process of 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….
try this code might help, modify it suit your needs
SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
Date d = format.parse(fileDate);
DateFormat.getDateInstance().format(dateInMS);
i finally find normal code that works for me
Long longDate = Long.valueOf(date);
Calendar cal = Calendar.getInstance();
int offset = cal.getTimeZone().getOffset(cal.getTimeInMillis());
Date da = new Date();
da = new Date(longDate-(long)offset);
cal.setTime(da);
String time =cal.getTime().toLocaleString();
//this is full string
time = DateFormat.getTimeInstance(DateFormat.MEDIUM).format(da);
//this is only time
time = DateFormat.getDateInstance(DateFormat.MEDIUM).format(da);
//this is only date
Short and effective:
DateFormat.getDateTimeInstance().format(new Date(myMillisValue))
Coverting epoch format to SimpleDateFormat in Android (Java / Kotlin)
input: 1613316655000
output: 2021-02-14T15:30:55.726Z
In Java
long milliseconds = 1613316655000L;
Date date = new Date(milliseconds);
String mobileDateTime = Utils.getFormatTimeWithTZ(date);
//method that returns SimpleDateFormat in String
public static String getFormatTimeWithTZ(Date currentTime) {
SimpleDateFormat timeZoneDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault());
return timeZoneString = timeZoneDate.format(currentTime);
}
In Kotlin
var milliseconds = 1613316655000L
var date = Date(milliseconds)
var mobileDateTime = Utils.getFormatTimeWithTZ(date)
//method that returns SimpleDateFormat in String
fun getFormatTimeWithTZ(currentTime:Date):String {
val timeZoneDate = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
return timeZoneString = timeZoneDate.format(currentTime)
}
Latest solution in Kotlin:
private fun getDateFromMilliseconds(millis: Long): String {
val dateFormat = "MMMMM yyyy"
val formatter = SimpleDateFormat(dateFormat, Locale.getDefault())
val calendar = Calendar.getInstance()
calendar.timeInMillis = millis
return formatter.format(calendar.time)
}
We need to add Locale as an argument of SimpleDateFormat or use LocalDate. Locale.getDefault() is a great way to let JVM automatically get the current location timezone.
public class LogicconvertmillistotimeActivity extends Activity {
/** Called when the activity is first created. */
EditText millisedit;
Button millisbutton;
TextView millistextview;
long millislong;
String millisstring;
int millisec=0,sec=0,min=0,hour=0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
millisedit=(EditText)findViewById(R.id.editText1);
millisbutton=(Button)findViewById(R.id.button1);
millistextview=(TextView)findViewById(R.id.textView1);
millisbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
millisbutton.setClickable(false);
millisec=0;
sec=0;
min=0;
hour=0;
millisstring=millisedit.getText().toString().trim();
millislong= Long.parseLong(millisstring);
Calendar cal = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
if(millislong>1000){
sec=(int) (millislong/1000);
millisec=(int)millislong%1000;
if(sec>=60){
min=sec/60;
sec=sec%60;
}
if(min>=60){
hour=min/60;
min=min%60;
}
}
else
{
millisec=(int)millislong;
}
cal.clear();
cal.set(Calendar.HOUR_OF_DAY,hour);
cal.set(Calendar.MINUTE,min);
cal.set(Calendar.SECOND, sec);
cal.set(Calendar.MILLISECOND,millisec);
String DateFormat = formatter.format(cal.getTime());
// DateFormat = "";
millistextview.setText(DateFormat);
}
});
}
}
I've been looking for an efficient way to do this for quite some time and the best I've found is:
DateFormat.getDateInstance(DateFormat.SHORT).format(new Date(millis));
Advantages:
It's localized
Been in Android since API 1
Very simple
Disadvantages:
Limited format options. FYI: SHORT is only a 2 digit year.
You burn a Date object every time. I've looked at source for the other options and this is a fairly minor compared to their overhead.
You can cache the java.text.DateFormat object, but it's not threadsafe. This is OK if you are using it on the UI thread.
This is the easiest way using Kotlin
private const val DATE_FORMAT = "dd/MM/yy hh:mm"
fun millisToDate(millis: Long) : String {
return SimpleDateFormat(DATE_FORMAT, Locale.US).format(Date(millis))
}
public static Date getDateFromString(String date) {
Date dt = null;
if (date != null) {
for (String sdf : supportedDateFormats) {
try {
dt = new Date(new SimpleDateFormat(sdf).parse(date).getTime());
break;
} catch (ParseException pe) {
pe.printStackTrace();
}
}
}
return dt;
}
public static Calendar getCalenderFromDate(Date date){
Calendar cal =Calendar.getInstance();
cal.setTime(date);return cal;
}
public static Calendar getCalenderFromString(String s_date){
Date date = getDateFromString(s_date);
Calendar cal = getCalenderFromDate(date);
return cal;
}
public static long getMiliSecondsFromString(String s_date){
Date date = getDateFromString(s_date);
Calendar cal = getCalenderFromDate(date);
return cal.getTimeInMillis();
}
public static String toDateStr(long milliseconds, String format)
{
Date date = new Date(milliseconds);
SimpleDateFormat formatter = new SimpleDateFormat(format, Locale.US);
return formatter.format(date);
}
Use SimpleDateFormat for Android N and above. Use the calendar for earlier versions
for example:
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
fileName = new SimpleDateFormat("yyyy-MM-dd-hh:mm:ss").format(new Date());
Log.i("fileName before",fileName);
}else{
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MONTH,1);
String zamanl =""+cal.get(Calendar.YEAR)+"-"+cal.get(Calendar.MONTH)+"-"+cal.get(Calendar.DAY_OF_MONTH)+"-"+cal.get(Calendar.HOUR_OF_DAY)+":"+cal.get(Calendar.MINUTE)+":"+cal.get(Calendar.SECOND);
fileName= zamanl;
Log.i("fileName after",fileName);
}
Output:
fileName before: 2019-04-12-07:14:47 // use SimpleDateFormat
fileName after: 2019-4-12-7:13:12 // use Calender
fun convertLongToTimeWithLocale(){
val dateAsMilliSecond: Long = 1602709200000
val date = Date(dateAsMilliSecond)
val language = "en"
val formattedDateAsDigitMonth = SimpleDateFormat("dd/MM/yyyy", Locale(language))
val formattedDateAsShortMonth = SimpleDateFormat("dd MMM yyyy", Locale(language))
val formattedDateAsLongMonth = SimpleDateFormat("dd MMMM yyyy", Locale(language))
Log.d("month as digit", formattedDateAsDigitMonth.format(date))
Log.d("month as short", formattedDateAsShortMonth.format(date))
Log.d("month as long", formattedDateAsLongMonth.format(date))
}
output:
month as digit: 15/10/2020
month as short: 15 Oct 2020
month as long : 15 October 2020
You can change the value defined as 'language' due to your require. Here is the all language codes:
Java language codes