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);
}
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.
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];
I have a ReST service which downloads information about events in a persons calendar...
When it returns the date and time, it returns them as a string
e.g. date = "12/8/2012" & time = "11:25 am"
To put this into the android calendar, I need to do the following:
Calendar beginTime = Calendar.getInstance();
beginTime.set(year, month, day, hour, min);
startMillis = beginTime.getTimeInMillis();
intent.put(Events.DTSTART, startMillis);
How can I split the date and time variables so that they are useable in the "beginTime.set() " method?
I don't thinks you really need how to split the string, in your case it should be 'how to get time in milliseconds from date string', here is an example:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateTest {
public static void main(String[] args) {
String date = "12/8/2012";
String time = "11:25 am";
DateFormat df = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
try {
Date dt = df.parse(date + " " + time);
Calendar ca = Calendar.getInstance();
ca.setTime(dt);
System.out.println(ca.getTimeInMillis());
} catch (ParseException e) {
e.printStackTrace();
}
}
}
Try this:
String date = "12/8/2012";
String time = "11:25 am";
String[] date1 = date.split("/");
String[] time1 = time.split(":");
String[] time2 = time1[1].split(" "); // to remove am/pm
Calendar beginTime = Calendar.getInstance();
beginTime.set(Integer.parseInt(date1[2]), Integer.parseInt(date1[1]), Integer.parseInt(date1[0]), Integer.parseInt(time1[0]), Integer.parseInt(time2[0]));
startMillis = beginTime.getTimeInMillis();
intent.put(Events.DTSTART, startMillis);
Hope this helps.
Assuming you get your date in String format (if not, convert it!) and then this:
String date = "12/8/2012";
String[] dateParts = date.split("/");
String day = dateParts[0];
String month = dateParts[1];
Similarly u can split time as well!
You can see an example of split method here : How to split a string in Java
Then simply use the array for your parameter eg: array[0] for year and etc..
Use SimpleDateFormat (check api docs). If you provide proper time pattern it will be able to convert string into Date instantly.
This is just a Idea, you can do some thing like this without splitting
DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy HH:mm a");
Date date = formatter.parse("12/8/2012 11:25 am");
Calendar cal=Calendar.getInstance();
cal.setTime(date);
java.time either through desugaring or through ThreeTenABP
Consider using java.time, the modern Java date and time API, for your date and time work. With java.time itâs straightforward to parse your two strings for date and time individually and then combine date and time into one object using LoalDate.atTime().
The way I read your code you are really after a count of milliseconds since the epoch. So this is what I am giving you in the first snippet. Feel free to take it apart and use only the lines you need.
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("d/M/u");
DateTimeFormatter timeFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("h:mm a")
.toFormatter(Locale.ENGLISH);
String dateString = "12/8/2012";
String timeString = "11:25 am";
LocalDate date = LocalDate.parse(dateString, dateFormatter);
LocalTime time = LocalTime.parse(timeString, timeFormatter);
long startMillis = date
.atTime(time)
.atZone(ZoneId.systemDefault())
.toInstant()
.toEpochMilli();
System.out.println(startMillis);
When running in my time zone (at UTC offset +02:00 in August) the output is:
1344763500000
For anyone reading along that does need the individual numbers from the two strings, getting those is straightforward too. For example:
int year = date.getYear();
Month month = date.getMonth();
int monthNumber = date.getMonthValue();
int dayOfMonth = date.getDayOfMonth();
int hourOfDay = time.getHour();
int hourWithinAmOrPm = time.get(ChronoField.HOUR_OF_AMPM);
int minute = time.getMinute();
System.out.format("Year %d month %s or %d day %d hour %d or %d AM/PM minute %d%n",
year, month, monthNumber, dayOfMonth, hourOfDay, hourWithinAmOrPm, minute);
Year 2012 month AUGUST or 8 day 12 hour 11 or 11 AM/PM minute 25
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.
I have a date format as "Nov 10,1980" in a string format(String str="Nov 10, 1980"), and i want to convert it to 1980-11-10. can any one tell me how to do that using java.
Thanks in advance
You should first parse it from the original text format, then format the result using the format you want it to end up as. You can use SimpleDateFormat for this, or Joda Time (which is generally a much better date/time API).
Sample code using SimpleDateFormat:
import java.text.*;
import java.util.*;
public class Test {
public static void main(String[] args) throws Exception {
String inputText = "Nov 10,1980";
TimeZone utc = TimeZone.getTimeZone("UTC");
// Or dd instead of d - it depends whether you'd use "Nov 08,1980"
// or "Nov 8,1980" etc.
SimpleDateFormat inputFormat = new SimpleDateFormat("MMM d,yyyy",
Locale.US);
inputFormat.setTimeZone(utc);
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd",
Locale.US);
outputFormat.setTimeZone(utc);
Date parsed = inputFormat.parse(inputText);
String outputText = outputFormat.format(parsed);
System.out.println(outputText); // 1980-11-10
}
}
Note that:
I've explicitly specified the locale to use; otherwise if you try to parse the text on a system with (say) a French default locale, it will try to parse it using French month names.
I've explicitly set the time zone as UTC to avoid any daylight saving time issues (where a particular value could be ambiguous or even non-existent in the default time zone)
Use this
Date date = new Date();
SimpleDateFormat sdf;
sdf = new SimpleDateFormat("yyyy-MM-DD");
System.out.println(sdf.format(date));
try {
SimpleDateFormat sdf1 = new SimpleDateFormat("MMM dd, yyyy");
Date strDt = sdf1.parse("Nov 10, 1980");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(sdf2.format(strDt));
} catch (Exception e) {
e.printStackTrace();
}
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*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("MMM d,u", Locale.ENGLISH);
LocalDate date = LocalDate.parse("Nov 10,1980", dtfInput);
System.out.println(date);
}
}
Output:
1980-11-10
ONLINE DEMO
Notice that I have not used a DateTimeFormatter to format the LocalDate because your desired format is the same as the ISO 8601 format which is also the standard used for java.time API. Check the LocalDate#toString documentation for more details.
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.
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String req_date = dateFormat.format(DATE)
System.out.println(req_date)
You can use two SimpleDateFormats. One to parse, one to format. For example:
public static void main(String[] args) throws ParseException {
DateFormat parseFormat = new SimpleDateFormat("MMM dd,yyyy");
DateFormat displayFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = parseFormat.parse("Nov 10,1980");
String s = displayFormat.format(date);
System.err.println(s);
}
Use the SimpleDateFormat to get the result you want
One of our customers wants to be able to enter a date with only 2 digits for the year component. The date will be in the past, so we want it to work for the previous century if the 2 digit year is after the current year, but work for the current century if the 2 digit year is equal to or less than the current year.
as of today 10/30/2008
01/01/01 = 01/01/2001
01/01/09 = 01/01/1909
This is a strange requirement, and I solved the problem, I just don't like my solution.
It feels like there is a better way to do this.
Thanks for the help.
public static String stupidDate(String dateString)
{
String twoDigitYear = StringUtils.right(dateString, 2);
String newDate = StringUtils.left(dateString, dateString.length() - 2);
int year = NumberUtils.toInt(twoDigitYear);
Calendar c = GregorianCalendar.getInstance();
int centuryInt = c.get(Calendar.YEAR) - year;
newDate = newDate + StringUtils.left(Integer.toString(centuryInt), 2) + twoDigitYear;
return newDate;
}
Groovy script (easy enough to throw into java) demonstrating the point #bobince made about SimpleDateFormat.
import java.text.SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat('MM/dd/yy')
SimpleDateFormat fmt = new SimpleDateFormat('yyyy-MM-dd')
Calendar cal = Calendar.getInstance()
cal.add(Calendar.YEAR, -100)
sdf.set2DigitYearStart(cal.getTime())
dates = ['01/01/01', '10/30/08','01/01/09']
dates.each {String d ->
println fmt.format(sdf.parse(d))
}
Yields
2001-01-01
2008-10-30
1909-01-01
SimpleDateFormat already does two-digit year parsing for you, using the two-letter âyyâ format. (It'll still allow four digits, obviously.)
By default it uses now-80ânow+20, so it's not exactly the same rule you propose, but it's reasonable and standardised (in the Java world at least), and can be overridden using set2DigitYearStart() if you want.
DateFormat informat= new SimpleDateFormat("MM/dd/yy");
DateFormat outformat= new SimpleDateFormat("MM/dd/yyyy");
return outformat.format(informat.parse(dateString));
In the longer term, try to migrate to ISO8601 date formatting (yyyy-MM-dd), because MM/dd/yy is approximately the worst possible date format and is bound to cause problems eventually.
How about this:
public static String anEasierStupidDateWithNoStringParsing(String dateString) {
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
//handling ParseExceptions is an exercise left to the reader!
Date date = df.parse(dateString);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
Calendar now = Calendar.getInstance();
if (cal.after(now)) {
cal.add(Calendar.YEAR, -100);
}
return cal;
}
In other words, let SimpleDateFormat parse the String and just adjust the year to be the previous century if SimpleDateFormat (which has it's own rules for interpreting year strings) returns a date that is after the current date.
This would guarantee that all dates returned are in the past. However, it doesn't account for any dates that might be parsed as before this past century - for example, with the format MM/dd/yyyy, a date string like "01/11/12" parses to Jan 11, 12 A.D.
If Joda Time is an option:
String inputDate = "01/01/08";
// assuming U.S. style date, since it's not clear from your original question
DateTimeFormatter parser = DateTimeFormat.forPattern("MM/dd/yy");
DateTime dateTime = parser.parseDateTime(inputDate);
// if after current time
if (dateTime.isAfter(new DateTime())) {
dateTime = dateTime.minus(Years.ONE);
}
return dateTime.toString("MM/dd/yyyy");
I know Joda Time isn't part of Java SE, and as I've said in another thread, I usually do not condone using a third-party library when there's a Java library that does the same thing. However, the person who is developing Joda Time is also leading JSR310 - the Date and Time API that'll make it into Java 7. So I Joda Time is basically going to be in future Java releases.
The accepted answer uses legacy date-time API which was the correct thing to do in 2008 when the question was asked. In March 2014, java.time API supplanted the error-prone legacy date-time API. Since then, it has been strongly recommended to use this modern date-time API.
java.time API
You can put optional patterns between DateTimeFormatterBuilder#optionalStart and DateTimeFormatterBuilder#optionalEnd and create a formatter which can parse a date string with either a four-digit year or a two-digit year.
Using the DateTimeFormatterBuilder#appendValueReduced, you can specify a base value for the year as per your requirement.
Demo:
import java.time.LocalDate;
import java.time.Year;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
DateTimeFormatter parser = new DateTimeFormatterBuilder()
.appendPattern("M/d/")
.optionalStart()
.appendPattern("uuuu")
.optionalEnd()
.optionalStart()
.appendValueReduced(ChronoField.YEAR, 2, 2, Year.now().minusYears(100).getValue())
.optionalEnd()
.toFormatter(Locale.ENGLISH);
// Test
Stream.of(
"1/2/2022",
"01/2/2022",
"1/02/2022",
"01/02/2022",
"1/2/22",
"1/2/21",
"1/2/20",
"1/2/23",
"1/2/24"
)
.map(s -> LocalDate.parse(s, parser))
.forEach(System.out::println);
}
}
Output:
2022-01-02
2022-01-02
2022-01-02
2022-01-02
1922-01-02
2021-01-02
2020-01-02
1923-01-02
1924-01-02
Note that the dates with a two-digit year greater than the current year are parsed into a LocalDate with the last century.
How to switch from the legacy to the modern date-time API?
You can switch from the legacy to the modern date-time API using Date#toInstant on a java-util-date instance. Once you have an Instant, you can easily obtain other date-time types of java.time API. An Instant represents a moment in time and is independent of a time-zone i.e. it represents a date-time in UTC (often displayed as Z which stands for Zulu-time and has a ZoneOffset of +00:00).
Demo:
public class Main {
public static void main(String[] args) {
Date date = new Date();
Instant instant = date.toInstant();
System.out.println(instant);
ZonedDateTime zdt = instant.atZone(ZoneId.of("Asia/Kolkata"));
System.out.println(zdt);
OffsetDateTime odt = instant.atOffset(ZoneOffset.of("+05:30"));
System.out.println(odt);
// Alternatively, using time-zone
odt = instant.atZone(ZoneId.of("Asia/Kolkata")).toOffsetDateTime();
System.out.println(odt);
LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.of("Asia/Kolkata"));
System.out.println(ldt);
// Alternatively,
ldt = instant.atZone(ZoneId.of("Asia/Kolkata")).toLocalDateTime();
System.out.println(ldt);
}
}
Output:
2022-11-20T20:32:42.823Z
2022-11-21T02:02:42.823+05:30[Asia/Kolkata]
2022-11-21T02:02:42.823+05:30
2022-11-21T02:02:42.823+05:30
2022-11-21T02:02:42.823
2022-11-21T02:02:42.823
Learn more about the modern Date-Time API from Trail: Date Time.
Date deliverDate = new SimpleDateFormat("MM/dd/yy").parse(deliverDateString);
String dateString2 = new SimpleDateFormat("yyyy-MM-dd").format(deliverDate);
Working for me.