I need to convert "11/17" string date (November 2017) to "2017-11-01" (November 1, 2017).
What is the best way to achieve this in Java?
I tried:
String dayMonthYear = "11/17";
dayMonthYear = "01/" + dayMonthYear;
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yy");
DateTime dt = formatter.parseDateTime(dayMonthYear);
dt.year().setCopy(dt.getYear() + 2000);
DateTimeFormatter dtfOut = DateTimeFormat.forPattern("yyyy-MM-dd");
dayMonthYear = dtfOut.print(dt);
System.out.println(dayMonthYear); // "2017-11-01";
And:
SimpleDateFormat dateFormatTwoDigitsYear = new SimpleDateFormat(TWO_DIGITS_YEAR_DATE_FORMAT); //"dd/MM/yy"
SimpleDateFormat dateFormatFourDigitsYear = new SimpleDateFormat(FOUR_DIGITS_YEAR_DATE_FORMAT);// "yyyy-MM-dd"
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, -100);//??? I AM NOT SURE WHY DO I NEEED THIS??
dateFormatTwoDigitsYear.set2DigitYearStart(calendar.getTime());
try
{
dayMonthYear = dateFormatFourDigitsYear.format(dateFormatTwoDigitsYear.parse(dayMonthYear));
}
catch (ParseException e)
{
log.error("Error while formatting date in yyyy-MM-dd format. Date is " + dayMonthYear);
}
I am not sure why I need this line in second appproach:
calendar.add(Calendar.YEAR, -100);
Both of them are working. But I am not sure if there is better solution.
You don't need to add values to the year. The 2 digit value (17) is automatically ajusted to 2017. Also, there's no need to append day 1 in the input. When the day is not present, SimpleDateFormat automatically sets to 1:
// input format: MM/yy
SimpleDateFormat parser = new SimpleDateFormat("MM/yy");
// output format: yyyy-MM-dd
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(formatter.format(parser.parse("11/17"))); // 2017-11-01
PS: if you need to set to another day (other than 1), you can set the date to a Calendar and change it before formatting:
// parse the date
Date date = parser.parse("11/17");
// set to a Calendar
Calendar cal = Calendar.getInstance();
cal.setTime(date);
// change to whatever day you want
cal.set(Calendar.DAY_OF_MONTH, whateverDayIwant);
// format it
System.out.println(formatter.format(cal.getTime()));
Joda-Time
The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.
I've seen you're using Joda-Time, so here's how to do it with this API.
In Joda-Time, when you parse to a DateTime, it sets default values for all the missing fields (in this case, day, hour, minute, etc). But this API has lots of other types that can suit best for each use case.
As the input has only month and year, you can parse it to a org.joda.time.YearMonth and then set the day to 1. This will create a org.joda.time.LocalDate, which can be printed directly (as the toString() method already returns the date in the format you want):
DateTimeFormatter parser = DateTimeFormat.forPattern("MM/yy");
// parse to YearMonth
YearMonth ym = YearMonth.parse("11/17", parser);
// set day to 1
System.out.println(ym.toLocalDate(1)); // 2017-11-01
I prefer this approach because you can set it to whatever day you want, and don't need to create a full DateTime object with fields that you don't need/care about (such as hour, minutes, etc).
If you need to store this value in a String, just call the toString() method:
// store "2017-11-01" in a String
String output = ym.toLocalDate(1).toString();
The format yyyy-MM-dd is the default used by toString(). If you need a different format, you can pass it to toString():
// convert to another format (example: dd/MM/yyyy)
String output = ym.toLocalDate(1).toString("dd/MM/yyyy"); // 01/11/2017
Or you can use another DateTimeFormatter:
// convert to another format (example: dd/MM/yyyy)
DateTimeFormatter fmt = DateTimeFormat.forPattern("dd/MM/yyyy");
String output = fmt.print(ym.toLocalDate(1)); // 01/11/2017
PS: dt.year().setCopy returns a new object, and as you don't assign it to any variable, this value is lost - this method doesn't change the original DateTime object, so dt is not changed by its line of code.
Java new date/time API
Joda-Time is in maintainance mode and is being replaced by the new APIs, so I don't recommend start a new project with it. Even in joda's website it says: "Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).".
If you can't (or don't want to) migrate from Joda-Time to the new API, you can ignore this section.
If you're using Java 8, consider using the new java.time API. It's easier, less bugged and less error-prone than the old APIs.
If you're using Java 6 or 7, you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. And for Android, you'll also need the ThreeTenABP (more on how to use it here).
The code below works for both.
The only difference is the package names (in Java 8 is java.time and in ThreeTen Backport (or Android's ThreeTenABP) is org.threeten.bp), but the classes and methods names are the same.
The code is very similar to Joda-Time (the API's are not exactly the same, but they have lots of similarities). You can use a Java 8's java.time.format.DateTimeFormatter and parse the input to a java.time.YearMonth (or, in Java 7's ThreeTen Backport, use a org.threeten.bp.format.DateTimeFormatter and parse to a org.threeten.bp.YearMonth):
DateTimeFormatter parser = DateTimeFormatter.ofPattern("MM/yy");
YearMonth ym = YearMonth.parse("11/17", parser);
System.out.println(ym.atDay(1)); // 2017-11-01
If you need to store this value in a String, just call the toString() method:
// store "2017-11-01" in a String
String output = ym.atDay(1).toString();
The format yyyy-MM-dd is the default used by toString(). If you need a different format, you can use another DateTimeFormatter:
// convert to another format (example: dd/MM/yyyy)
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String output = fmt.format(ym.atDay(1)); // 01/11/2017
You can define two utility methods one converting the string to date and the other converting it back to string.
static Date stringToDate(String string) throws ParseException
{
DateFormat dateFormat = new SimpleDateFormat("MM/yyyy");
return dateFormat.parse(string);
}
static String dateToString(Date date)
{
DateFormat outputFormatter = new SimpleDateFormat("yyyy-MM-dd");
return outputFormatter.format(date);
}
static String formatString(String string)
{
return dateToString(stringToDate(string));
}
//Just call formatString() with your argument
You can combine them if you only intend to convert the first string type to the second type but I like to keep them separate in case I need a date object from string or string directly from a date object.
Related
There is a call to some external system which returns a date in hijri. In Production env, we received it as '30-02-1436'.
Consider the snippet which converts the hijri to a gregorian date, but it fails to do so.
public static String convertHijriToGregorianDate(String hijriDate){
Chronology iso = ISOChronology.getInstanceUTC(); // get the ISO standard chronology which we follow now
Chronology hijri = IslamicChronology.getInstanceUTC(); // the hijri based chronology
//String hijriDate = "19-08-1435"; // example/format which is received as a parameter in the method from response
if(null != hijriDate && !hijriDate.isEmpty()){
String[] parts = hijriDate.trim().split("-"); // you will get an array of size 3 by splitting with regex '-'
String hijriYear = parts[2];
String hijriMonth = parts[1];
String hijriDay = parts[0];
// Construct the Local Date corresponding to the hijri chronology
LocalDate todayHijri = new LocalDate(Integer.parseInt(hijriYear), Integer.parseInt(hijriMonth), Integer.parseInt(hijriDay), hijri);
// Construct the Local Date corresponding to the iso chronology based on the hijri date
LocalDate todayIso = new LocalDate(todayHijri.toDateTimeAtStartOfDay(), iso);
return String.valueOf(todayIso);
}
return null;
}
Please suggest as to what is wrong with the code. We are getting this issue in stacktrace-
org.joda.time.IllegalFieldValueException: Value 30 for dayOfMonth must
be in the range [1,29]
at org.joda.time.field.FieldUtils.verifyValueBounds(FieldUtils.java:252)
at org.joda.time.chrono.BasicChronology.getDateMidnightMillis(BasicChronology.java:632)
at org.joda.time.chrono.BasicChronology.getDateTimeMillis0(BasicChronology.java:186)
at org.joda.time.chrono.BasicChronology.getDateTimeMillis(BasicChronology.java:160)
at org.joda.time.chrono.LimitChronology.getDateTimeMillis(LimitChronology.java:177)
at org.joda.time.chrono.BasicChronology.getDateTimeMillis(BasicChronology.java:155)
at org.joda.time.LocalDate.(LocalDate.java:457)
Joda time version used is 2.9.1
I have checked all available leap year patterns (=4) in Joda-Time by the expression
Chronology hijri =
IslamicChronology.getInstance(DateTimeZone.UTC, IslamicChronology.LEAP_YEAR_15_BASED);
Unfortunately nothing works for you. However, the umalqura-calendar of Saudi-Arabia considers '30-02-1436' as valid. It corresponds to the gregorian date 2014-12-22.
Joda-Time does not support this variant of islamic calendar so you cannot do anything here unless you are willing to migrate to Java-8 which contains the umalqura-variant.
System.out.println(HijrahDate.of(1436, 2, 30)); // Hijrah-umalqura AH 1436-02-30
DateTimeFormatter fh =
DateTimeFormatter.ofPattern(
"dd-MM-yyyy",
Locale.forLanguageTag("en")
).withChronology(HijrahChronology.INSTANCE);
System.out.println(HijrahDate.from(fh.parse(input)));
// Hijrah-umalqura AH 1436-02-30
System.out.println(LocalDate.from(HijrahDate.from(fh.parse(input))));
// 2014-12-22
Note: The unicode extension Locale.forLanguageTag("en-u-ca-islamic-umalqura") does unfortunately not seem to work in my experiments so specifying the chronology explicitly is necessary.
Alternative:
If you cannot migrate to Java-8 or even need more features of islamic calendar (for example other variants like those used in Joda-Time) then you might also try out my library Time4J:
String input = "30-02-1436";
ChronoFormatter<HijriCalendar> hf =
ChronoFormatter.ofPattern(
"dd-MM-yyyy",
PatternType.CLDR,
Locale.ROOT,
HijriCalendar.family()
).withCalendarVariant(HijriCalendar.VARIANT_UMALQURA).with(Leniency.STRICT);
System.out.println(hf.parse(input)); // AH-1436-02-30[islamic-umalqura]
System.out.println(hf.parse(input).transform(PlainDate.axis())); // 2014-12-22
The date is interpreted as Feb 30, but this month must have fewer than 30 days in it. This explains the error message. So correct the input so it corresponds to a date that is possible.
I am trying to convert the string to date and i want that date to be in this format 'yyyy-MM-d HH:mm:ss' and i no how to get this format in string my question is i want to get Date in above format not as string but as 'Date '?
i am doing in this way
for(int k=0;k<12;k++)//for the months
{
//i have added if condtion for the months with 31 and 30 and 28 days
Calendar dateFromCal = Calendar.getInstance();
dateFromCal.setTime(date);
dateFromCal.set(year, k, 1, 0, 0, 0);
Calendar dateToCal = Calendar.getInstance();
dateToCal.setTime(date);
dateToCal.set(year, k, 31, 23, 59, 59);
//i have set the date format as 'yyyy:MM:dd HH:mm:ss'
dateFrom = dateFormat.format(dateFromCal.getTime());
dateTo = dateFormat.format(dateToCal.getTime());
fromdate = (Date)dateFormat.parse(dateFrom);
todate = (Date)dateFormat.parse(dateTo);
}
by using above code i am getting the date in the following format
Sat Nov 01 00:00:00 GMT 2014
but i want the date format to be as
2014-11-01 00:00:00
NOTE:I want this result as Date not as String
Please give me solution for this
Thanks....
i want to get Date in above format not as string but as 'Date '?
You're asking for a Date in a particular format - that's like saying "I want an int in hex format." A Date doesn't have a format - it's just an instant in time. It doesn't know about a calendar system or a time zone - it's just a number of milliseconds since the Unix epoch. If you want a formatted value, that's a string.
You should probably just keep the Date as it is, and format it later on, closer to the UI.
NOTE:I want this result as Date not as String
Short answer: It is NOT possible.
Details:
A java.util.Date object simply represents an instant on the timeline — a wrapper around the number of milliseconds since the UNIX epoch (January 1, 1970, 00:00:00 GMT). Since it does not hold any timezone information, its toString function applies the JVM's timezone to return a String in the format, EEE MMM dd HH:mm:ss zzz yyyy, derived from this milliseconds value. To get the String representation of the java.util.Date object in a different format and timezone, you need to use SimpleDateFormat with the desired format and the applicable timezone e.g.
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String strDateNewYork = sdf.format(date);
sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
String strDateUtc = sdf.format(date);
In fact, none of the standard Date-Time classes has an attribute to hold the formatting information. Even if some library or custom class promises to do so, it is breaking the Single Responsibility Principle. A Date-Time object is supposed to store the information about Date, Time, Timezone etc., not about the formatting. The only way to represent a Date-Time object in the desired format is by formatting it into a String using a Date-Time parsing/formatting type:
For the modern Date-Time API: java.time.format.DateTimeFormatter
For the legacy Date-Time API: java.text.SimpleDateFormat
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.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
int year = 2021;
int month = 6;
int hour = 23;
int minute = 59;
int second = 59;
LocalDateTime ldt = LocalDate.of(year, month, 1)
.with(TemporalAdjusters.lastDayOfMonth())
.atTime(LocalTime.of(hour, minute, second));
// Default format i.e. ldt#toString
System.out.println(ldt);
// Custom format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
String formatted = dtf.format(ldt);
System.out.println(formatted);
}
}
Output:
2021-06-30T23:59:59
2021-06-30 23:59:59
ONLINE DEMO
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.
I had same problem with one API that was expecting particular format (javax.xml.datatype.XMLGregorianCalendar). In my case I solve this by the help of java 7
and
my_date.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
By doing so you can get your final result for date with 00:00:00.
This is a simple method that takes care of formatting from String to Date:
` see code below:
public XMLGregorianCalendar formatToGregorianDate(String myDate) {
//actual Date format should be "dd-MMM-yy", but SimpleDateFormat accepts only this one
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
//Date is accepted only without time or zone
date = simpleDateFormat.parse(myDate.substring(0, 10));
} catch (ParseException e) {
System.out.println("Date can't be parsed to required format!");
e.printStackTrace();
}
GregorianCalendar gregorianCalendar = (GregorianCalendar) GregorianCalendar.getInstance();
gregorianCalendar.setTime(date);
XMLGregorianCalendar result = null;
try {
result = DatatypeFactory.newInstance().newXMLGregorianCalendar(gregorianCalendar);
//date must be sent without time
result.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
} catch (DatatypeConfigurationException e) {
System.out.println("XMLGregorianCalendar can't parse the Date format!");
e.printStackTrace();
}
return result;
}`
Maybe you'll just need to adapt it for your needs, I don't know what do you need.
FYI - Note that I'm using java.util.Date. Maybe there is better logic, but this one works for sure.
Hope it helps.
// Im new to java programming
I have a String object that represents a date/time in this format : "2013-06-09 14:20:00" (yyyy-MM-dd HH:mm:ss)
I want to convert it to a Date object so i can perform calculations on it but im confused on how to do this.
I tried :
String string = "2013-06-09 14:20:00";
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(string);
System.out.println(date);
//Prints Mon Dec 31 00:00:00 GMT 2012
Any help appreciated
Ok so I have now updated my code to as follows i'm getting the correct date/time now when I print the date but is this the correct implementation :
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String string = "2013-06-09 14:20:00";
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(string);
System.out.println(dateFormat.format(date));
//prints 2013-06-09 14:20:00
Thx to everyone that's answered/commented thus far
The format is wrong. Use this instead:
"yyyy-dd-MM HH:mm:ss"
Indeed your last program version is ok, except you don't need to declare the SimpleDateFormat twice. Simply:
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String string = "2013-06-09 14:20:00";
Date date = dateFormat.parse(string);
System.out.println(dateFormat.format(date));
String string = "2013-06-09 14:20:00";
and the DATE object format is "yyyy-dd-MM HH:mm:ss"
You can get Date,Day,month and many more by using Date object which is present in
java.util.Date package , like as follows.
Date d = new Date(string);
This will call constructor of Date object for which you are passing 'string' variable which contains date.
d.getDay(); // retrieve day on that particular day
d.getDate(); // retrieve Date
and many more are avaiable like this.
Using java.util.Date
The answer by zzKozak is correct. Well, almost correct. The example code omits required exception handling. Like this…
java.text.DateFormat dateFormat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String string = "2013-06-09 14:20:00";
Date date = null;
try {
date = dateFormat.parse(string);
} catch ( ParseException e ) {
e.printStackTrace();
}
System.out.println("date: " + dateFormat.format(date));
Don't Use java.util.Date!
Avoid using java.util.Date & Calendar classes bundled with Java. They are notoriously bad in both design and implementation.
Instead use a competent date-time library. In Java that means either:
The third-party open-source Joda-Time
In the forthcoming Java 8, the new java.time.* classes defined by JSR 310 and inspired by Joda-Time.
Time Zone
Your question and code fail to address the issue of time zones. If you ignore time zones, you'll get defaults. That may cause unexpected behaviors when deployed in production. Better practice is to always specify a time zone.
Formatter
If you replace a space with a 'T' per the standard ISO 8601 format, then you can conveniently feed that string directly to a constructor of a Joda-Time DateTime instance.
If you must use that string as-is, then define a formatter to specify that format. You can find many examples of that here on StackOverflow.com.
Example Code
Here is some example code using Joda-Time 2.3, running in Java 7.
I arbitrarily chose a time zone of Montréal.
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// import org.joda.time.*;
// import org.joda.time.format.*;
// Specify a time zone rather than rely on default.
// Necessary to handle Daylight Saving Time (DST) and other anomalies.
DateTimeZone timeZone = DateTimeZone.forID( "America/Montreal" );
DateTime dateTime = new DateTime( "2013-06-09T14:20:00", timeZone ); // Or pass DateTimeZone.UTC as time zone for UTC/GMT.
System.out.println( "dateTime: " + dateTime );
When run…
dateTime: 2013-06-09T14:20:00.000-04:00
I am trying to convert Json date string to java date format. However, it gives error when it comes to "return df.parse( tarih )" line.
JSON :
{"DateFrom":"\/Date(1323087840000+0200)\/"}
Java code :
private Date JSONTarihConvert(String tarih) throws ParseException
{
SimpleDateFormat df = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ssz" );
if ( tarih.endsWith( "Z" ) ) {
tarih = tarih.substring( 0, tarih.length() - 1) + "GMT-00:00";
} else {
int inset = 6;
String s0 = tarih.substring( 6, tarih.length()-1 - inset );
String s1 = tarih.substring( tarih.length()- inset,tarih.length()-2 );
tarih = s0 + "GMT" + s1;
}
return df.parse( tarih );
}
When I call this method, tarih parameter is: /Date(1323087840000+0200)/
As you're interested in a Date object and the JSON occurs to me to be a unix timestamp.
Therefore I'd recommend you the Date(long milliseconds) constructor :)
private Date JSONTarihConvert(String tarih) throws ParseException{
long timestamp = getTimeStampFromTarih(tarih);
return new Date(timestamp);
}
Where getTimeStampFromTarih extracts the milliseconds before the occurrence of "+"
This will work surely
String date = "/Date(1376841597000)/";
Calendar calendar = Calendar.getInstance();
String datereip = date.replace("/Date(", "").replace(")/", "");
Long timeInMillis = Long.valueOf(datereip);
calendar.setTimeInMillis(timeInMillis);
System.out.println(calendar.getTime().toString("dd-MMM-yyyy h:mm tt"));//It Will Be in format 29-OCT-2014 2:26 PM
First replace string like this :
String str= ConvertMilliSecondsToFormattedDate(strDate.replace("/Date(","").replace(")/", ""));
Then Convert it like this:
public static String ConvertMilliSecondsToFormattedDate(String milliSeconds){
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(Long.parseLong(milliSeconds));
return simpleDateFormat.format(calendar.getTime());
}
You will Need to type cast date:
String rawdate = "/Date(1995769286000)/";
Calendar calendarins = Calendar.getInstance();
String datereip = rawdate.replace("/Date(", "").replace(")/", "");
Long timeInMillis = Long.valueOf(datereip);
calendar.setTimeInMillis(timeInMillis);
System.out.println(calendar.getTime().toString("dd-MMM-yyyy h:mm tt"));
Unless you have a reason not to, you should be using a parser to serialize and de-serialize objects. Like Jackson parser.
java.time
This is the modern answer (since 2014).
First I want to make sure the timestamp I have really lives up to the format I expect. I want to make sure if one day it doesn’t, I don’t just pretend and the user will get incorrect results without knowing they are incorrect. So for parsing the timestamp string, since I didn’t find a date-time format that would accept milliseconds since the epoch, I used a regular expression:
String time = "/Date(1479974400000-0800)/";
Pattern pat = Pattern.compile("/Date\\((\\d+)([+-]\\d{4})\\)/");
Matcher m = pat.matcher(time);
if (m.matches()) {
Instant i = Instant.ofEpochMilli(Long.parseLong(m.group(1)));
System.out.println(i);
}
This prints:
2016-11-24T08:00:00Z
It is not clear to me whether you need to use the zone offset and for what purpose. But since we’ve got it, why not retrieve it from the matcher and use it for forming an OffsetDateTime, a date and time with UTC offset. Here’s how:
ZoneOffset zo = ZoneOffset.of(m.group(2));
OffsetDateTime odt = OffsetDateTime.ofInstant(i, zo);
System.out.println(odt);
2011-12-05T14:24+02:00
If you need an old-fashioned java.util.Date for some legacy API:
System.out.println(Date.from(i));
Or if using the backport mentioned in the links below:
System.out.println(DateTimeUtils.toDate(i));
On my computer it prints
Mon Dec 05 13:24:00 CET 2011
The exact output will depend on your time zone.
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.
This question already has answers here:
How to add time to the current time?
(3 answers)
Closed 1 year ago.
I have the following requirement in the project.
I have a input field by name startDate and user enters in the format YYYY-MM-DD HH:MM:SS.
I need to add two hours for the user input in the startDate field. how can i do it.
Thanks in advance
You can use SimpleDateFormat to convert the String to Date. And after that you have two options,
Make a Calendar object and and then use that to add two hours, or
get the time in millisecond from that date object, and add two hours like, (2 * 60 * 60 * 1000)
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// replace with your start date string
Date d = df.parse("2008-04-16 00:05:05");
Calendar gc = new GregorianCalendar();
gc.setTime(d);
gc.add(Calendar.HOUR, 2);
Date d2 = gc.getTime();
Or,
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// replace with your start date string
Date d = df.parse("2008-04-16 00:05:05");
Long time = d.getTime();
time +=(2*60*60*1000);
Date d2 = new Date(time);
Have a look to these tutorials.
SimpleDateFormat Tutorial
Calendar Tutorial
Being a fan of the Joda Time library, here's how you can do it that way using a Joda DateTime:
import org.joda.time.format.*;
import org.joda.time.*;
...
String dateString = "2009-04-17 10:41:33";
// parse the string
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
DateTime dateTime = formatter.parseDateTime(dateString);
// add two hours
dateTime = dateTime.plusHours(2); // easier than mucking about with Calendar and constants
System.out.println(dateTime);
If you still need to use java.util.Date objects before/after this conversion, the Joda DateTime API provides some easy toDate() and toCalendar() methods for easy translation.
The Joda API provides so much more in the way of convenience over the Java Date/Calendar API.
Try this one, I test it, working fine
Date date = null;
String str = "2012/07/25 12:00:00";
DateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
date = formatter.parse(str);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.HOUR, 2);
System.out.println(calendar.getTime()); // Output : Wed Jul 25 14:00:00 IST 2012
If you want to convert in your input type than add this code also
formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
str=formatter.format(calendar.getTime());
System.out.println(str); // Output : 2012-07-25 14:00:00
Use the SimpleDateFormat class parse() method. This method will return a Date object. You can then create a Calendar object for this Date and add 2 hours to it.
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = formatter.parse(theDateToParse);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.HOUR_OF_DAY, 2);
cal.getTime(); // This will give you the time you want.
//the parsed time zone offset:
DateTimeFormatter dateFormat = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
String fromDateTimeObj = "2011-01-03T12:00:00.000-0800";
DateTime fromDatetime = dateFormat.withOffsetParsed().parseDateTime(fromDateTimeObj);
Basic program of adding two times:
You can modify hour:min:sec as per your need using if else.
This program shows you how you can add values from two objects and return in another object.
class demo
{private int hour,min,sec;
void input(int hour,int min,int sec)
{this.hour=hour;
this.min=min;
this.sec=sec;
}
demo add(demo d2)//demo because we are returning object
{ demo obj=new demo();
obj.hour=hour+d2.hour;
obj.min=min+d2.min;
obj.sec=sec+d2.sec;
return obj;//Returning object and later on it gets allocated to demo d3
}
void display()
{
System.out.println(hour+":"+min+":"+sec);
}
public static void main(String args[])
{
demo d1=new demo();
demo d2=new demo();
d1.input(2, 5, 10);
d2.input(3, 3, 3);
demo d3=d1.add(d2);//Note another object is created
d3.display();
}
}
Modified Time Addition Program
class demo
{private int hour,min,sec;
void input(int hour,int min,int sec)
{this.hour=(hour>12&&hour<24)?(hour-12):hour;
this.min=(min>60)?0:min;
this.sec=(sec>60)?0:sec;
}
demo add(demo d2)
{ demo obj=new demo();
obj.hour=hour+d2.hour;
obj.min=min+d2.min;
obj.sec=sec+d2.sec;
if(obj.sec>60)
{obj.sec-=60;
obj.min++;
}
if(obj.min>60)
{ obj.min-=60;
obj.hour++;
}
return obj;
}
void display()
{
System.out.println(hour+":"+min+":"+sec);
}
public static void main(String args[])
{
demo d1=new demo();
demo d2=new demo();
d1.input(12, 55, 55);
d2.input(12, 7, 6);
demo d3=d1.add(d2);
d3.display();
}
}
This example is a Sum for Date time and Time Zone(String Values)
String DateVal = "2015-03-26 12:00:00";
String TimeVal = "02:00:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm:ss");
Date reslt = sdf.parse( DateVal );
Date timeZ = sdf2.parse( TimeVal );
//Increase Date Time
reslt.setHours( reslt.getHours() + timeZ.getHours());
reslt.setMinutes( reslt.getMinutes() + timeZ.getMinutes());
reslt.setSeconds( reslt.getSeconds() + timeZ.getSeconds());
System.printLn.out( sdf.format(reslt) );//Result(+2 Hours): 2015-03-26 14:00:00
Thanks :)
This will give you the time you want (eg: 21:31 PM)
//Add 2 Hours to just TIME
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss a");
Date date2 = formatter.parse("19:31:51 PM");
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
cal2.add(Calendar.HOUR_OF_DAY, 2);
SimpleDateFormat printTimeFormat = new SimpleDateFormat("HH:mm a");
System.out.println(printTimeFormat.format(cal2.getTime()));
tl;dr
LocalDateTime.parse(
"2018-01-23 01:23:45".replace( " " , "T" )
).plusHours( 2 )
java.time
The modern approach uses the java.time classes added to Java 8, Java 9, and later.
user enters in the format YYYY-MM-DD HH:MM:SS
Parse that input string into a date-time object. Your format is close to complying with standard ISO 8601 format, used by default in the java.time classes for parsing/generating strings. To fully comply, replace the SPACE in the middle with a T.
String input = "2018-01-23 01:23:45".replace( " " , "T" ) ; // Yields: 2018-01-23T01:23:45
Parse as a LocalDateTime given that your input lacks any indicator of time zone or offset-from-UTC.
LocalDateTime ldt = LocalDateTime.parse( input ) ;
add two hours
The java.time classes can do the math for you.
LocalDateTime twoHoursLater = ldt.plusHours( 2 ) ;
Time Zone
Be aware that a LocalDateTime does not represent a moment, a point on the timeline. Without the context of a time zone or offset-from-UTC, it has no real meaning. The “Local” part of the name means any locality or no locality, rather than any one particular locality. Just saying "noon on Jan 21st" could mean noon in Auckland, New Zealand which happens several hours earlier than noon in Paris France.
To define an actual moment, you must specify a zone or offset.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ; // Define an actual moment, a point on the timeline by giving a context with time zone.
If you know the intended time zone for certain, apply it before adding the two hours. The LocalDateTime class assumes simple generic 24-hour days when doing the math. But in various time zones on various dates, days may be 23 or 25 hours long, or may be other lengths. So, for correct results in a zoned context, add the hours to your ZonedDateTime rather than LocalDateTime.
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.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
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, 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.