Date formatting not working - java

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.

Related

How to format LocalDate to ISO 8601 with T and Z?

I'm trying to generate a random date and time, and convert it to the "yyyy-MM-dd'T'HH:mm:ss'Z'" format.
Here is what I have tried:
public static String generateRandomDateAndTimeInString() {
LocalDate date = LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70))));
System.out.println("date and time :: " + date.toString());
return formatDate(date) ;
}
public static String formatDate(LocalDate date){
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
return dateFormat.format(date);
}
But in the line dateFormat.format(date), it complains with:
java.lang.IllegalArgumentException: Cannot format given Object as a Date
The second problem is that, the output of print does not contain the time:
date :: 1998-12-24
I don't know how to get it to work.
Never format the java.time types using SimpleDateFormat
Using the SimpleDateFormat, you are supposed to format only legacy date-time types e.g. java.util.Date. In order to format the java.time date-time types, you need to use DateTimeFormatter.
Never enclose Z within single quotes
It's a blunder to enclose Z within single quotes in a format. The symbol Z stands for zulu and specifies UTC+00:00. If you enclose it within single quotes, it will simply mean character literal, Z and won't function as UTC+00:00 on parsing.
You do not need to use a formatter explicitly
For this requirement, you do not need to use a formatter explicitly because the OffsetDateTime#toString already returns the string in the format that you need. However, if the number of seconds in an OffsetDateTime object is zero, the same and the subsequent smaller units are truncated by OffsetDateTime#toString. If you need the full format irrespective of the value of seconds, then, of course, you will have to use DateTimeFormatter.
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Random;
public class Main {
public static void main(String[] args) {
System.out.println(generateRandomDateAndTimeInString());
}
public static String generateRandomDateAndTimeInString() {
LocalDate date = LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70))));
System.out.println("date and time :: " + date.toString());
return formatDate(date);
}
public static String formatDate(LocalDate date) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
// return date.atStartOfDay().atOffset(ZoneOffset.UTC).toString();
return date.atStartOfDay().atOffset(ZoneOffset.UTC).format(dtf);
}
}
A sample run:
date and time :: 1996-09-05
1996-09-05T00:00:00Z
Note that the date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API.
For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7.
If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Learn more about the modern date-time API from Trail: Date Time.
If you still need to use SimpleDateFormat for whatsoever reason:
Convert LocalDate to ZonedDateTime with ZoneOffset.UTC and at the start of the day ➡️ Convert ZonedDateTime to Instant ➡️ Obtain java.util.Date object from Instant.
public static String formatDate(LocalDate date) {
Date utilDate = Date.from(date.atStartOfDay(ZoneOffset.UTC).toInstant());
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
return dateFormat.format(utilDate);
}
If you want to ignore the time part then you can use ZonedDateTime like this:
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");
return ZonedDateTime.of(
date,
LocalTime.MIN,
ZoneId.of("Europe/Paris")
).format(dateFormat);
Output example
2013-10-19T00:00:00+0200
Or much better, you can use just toString to get a formatted date as a String with the default format of ZonedDateTime:
return ZonedDateTime.of(
date,
LocalTime.MIN,
ZoneId.of("Europe/Paris")
).toString();
Output
2013-10-19T00:00+02:00[Europe/Paris]
Note
This date are always with 00:00:00 for time part, because we are using LocalTime.MIN
Also, you can change the ZoneId to the expected Zone, this was just an example.
Important
DateFormat and SimpleDateFormat are legacy library, so please don't mix them with the java.time library, in the top you are using LocalDate which mean you are using this java.time library so keep going with it in all your code.
ZoneOffset utc = ZoneOffset.UTC;
LocalDate today = LocalDate.now(utc);
LocalDate seventyYearsAgo = today.minusYears(70);
int totalDays = Math.toIntExact(ChronoUnit.DAYS.between(seventyYearsAgo, today));
LocalDate date = today.minusDays(new Random().nextInt(totalDays));
String dateString = date.atStartOfDay(utc).toString();
System.out.println("date and time :: " + dateString);
Example output:
date and time :: 1983-08-24T00:00Z
Points to note:
Let java.time convert from years to days. It gives more readable and more correct code (a year is not always 365 days).
To have time of day and UTC offset in the string, convert a ZonedDateTime or an OffsetDateTime since such objects hold time of day and offset. A LocalDate does not. It’s a date without time of day and without offset from UTC. The Z you asked for denotes an offset of 0 from UTC.
If you want hours, minutes and seconds in the output too, you can have that by counting seconds rather than days. In this case use OffsetDateTime for the entire operation (or ZonedDateTime if in a time zone different from UTC).
ZoneOffset utc = ZoneOffset.UTC;
OffsetDateTime today = OffsetDateTime.now(utc).truncatedTo(ChronoUnit.SECONDS);
OffsetDateTime seventyYearsAgo = today.minusYears(70);
long totalSeconds = ChronoUnit.SECONDS.between(seventyYearsAgo, today);
OffsetDateTime date = today.minusSeconds(ThreadLocalRandom.current().nextLong(0, totalSeconds));
String dateString = date.toString();
System.out.println("date and time :: " + dateString);
date and time :: 1996-09-21T06:49:56Z
I am using ThreadLocalRandom because it can generate a random long value in a specified interval. Funnily ThreadLocalRandom has a lot of convenient methods that Random hasn’t got.

Get date by utc/gmt in Android

I want to display the time in some Country, and the TimeZone is GMT+4.
private void loadWeather(){
TimeZone tz = TimeZone.getTimeZone("GMT+0400");
Calendar cal = Calendar.getInstance(tz);
Date date = cal.getTime();
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT,DateFormat.SHORT, Locale.getDefault());
String myDate = df.format(date);
tv_time.setText(myDate);
}
I've tried this, but it gives me my time, and not the other one
The problem is that you're specifying the time zone just on the Calendar - which is only used to get the current instant in time, which doesn't depend on the time zone. You need to specify it on the format instead, so that it's applied when creating an appropriate text representation of that instant:
private void loadWeather() {
Date date = new Date(); // This is enough; it uses the current instant.
DateFormat df = DateFormat.getDateTimeInstance(
DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault());
df.setTimeZone(TimeZone.getTimeZone("GMT+0400"));
String myDate = df.format(date);
tv_time.setText(myDate);
}
Or to inline even more:
private void loadWeather() {
DateFormat df = DateFormat.getDateTimeInstance(
DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault());
df.setTimeZone(TimeZone.getTimeZone("GMT+0400"));
tv_time.setText(df.format(new Date()));
}
(This is assuming you really do want the short date/time format using the current locale.)
I want to display the time in some Country, and the TimeZone is GMT+4.
GMT+4 is not a time zone. A time zone is represented as Region/City e.g. Europe/London. Check the List of tz database time zones for more examples. GMT+4 means time zone offset i.e. 4 hours ahead of UTC and therefore, in order to get the equivalent date-time at UTC, one has to subtract 4 hours from the date-time at GMT+4.
GMT+4 is not the standard way to represent time zone offset
The standard format is +/-HH:mm:ss or Z which refers to +00:00 offset. In most cases, you will see +/-HH:mm e.g. +06:00. Check this Wikipedia link to learn more about it.
java.time
The java.util date-time API and their corresponding parsing/formatting type, SimpleDateFormat are outdated and error-prone. In March 2014, the modern Date-Time API was released as part of the Java 8 standard library which supplanted the legacy date-time API and since then it is strongly recommended to switch to java.time, the modern date-time API.
Solution using java.time
To represent a date-time with time zone offset, the Java 8+ standard library provides java.time.OffsetDateTime.
Demo:
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
class Main {
public static void main(String[] args) {
OffsetDateTime now = OffsetDateTime.now(ZoneOffset.of("+04:00"));
System.out.println(now);
// The corresponding date-time at UTC
System.out.println(now.toInstant());
// Alternatively
System.out.println(now.withOffsetSameInstant(ZoneOffset.UTC));
}
}
The output from a sample run:
2023-02-04T14:08:58.657721+04:00
2023-02-04T10:08:58.657721Z
2023-02-04T10:08:58.657721Z
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
Use SimpleDateFormat as below and set the TimeZone to the SimpleDateFormat object...I think, you will get the problem right.
Calendar calendar = Calendar.getInstance();
SimpleDateFormat dateFormatGmt = new SimpleDateFormat("dd:MM:yyyy HH:mm:ss");
dateFormatGmt.setTimeZone(TimeZone.getTimeZone("GMT+0400"));
String date = dateFormatGmt.format(calendar.getTime());

How to convert date in to yyyy-MM-dd Format?

Sat Dec 01 00:00:00 GMT 2012
I have to convert above date into below format
2012-12-01
How can i?
i have tried with following method but its not working
public Date ConvertDate(Date date){
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String s = df.format(date);
String result = s;
try {
date=df.parse(result);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return date;
}
Use this.
java.util.Date date = new Date("Sat Dec 01 00:00:00 GMT 2012");
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String format = formatter.format(date);
System.out.println(format);
you will get the output as
2012-12-01
String s;
Format formatter;
Date date = new Date();
// 2012-12-01
formatter = new SimpleDateFormat("yyyy-MM-dd");
s = formatter.format(date);
System.out.println(s);
UPDATE My Answer here is now outdated. The Joda-Time project is now in maintenance mode, advising migration to the java.time classes. See the modern solution in the Answer by Ole V.V..
Joda-Time
The accepted answer by NidhishKrishnan is correct.
For fun, here is the same kind of code in Joda-Time 2.3.
// © 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.*;
java.util.Date date = new Date(); // A Date object coming from other code.
// Pass the java.util.Date object to constructor of Joda-Time DateTime object.
DateTimeZone kolkataTimeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeInKolkata = new DateTime( date, kolkataTimeZone );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "yyyy-MM-dd");
System.out.println( "dateTimeInKolkata formatted for date: " + formatter.print( dateTimeInKolkata ) );
System.out.println( "dateTimeInKolkata formatted for ISO 8601: " + dateTimeInKolkata );
When run…
dateTimeInKolkata formatted for date: 2013-12-17
dateTimeInKolkata formatted for ISO 8601: 2013-12-17T14:56:46.658+05:30
Modern answer: Use LocalDate from java.time, the modern Java date and time API, and its toString method:
LocalDate date = LocalDate.of(2012, Month.DECEMBER, 1); // get from somewhere
String formattedDate = date.toString();
System.out.println(formattedDate);
This prints
2012-12-01
A date (whether we’re talking java.util.Date or java.time.LocalDate) doesn’t have a format in it. All it’s got is a toString method that produces some format, and you cannot change the toString method. Fortunately, LocalDate.toString produces exactly the format you asked for.
The Date class is long outdated, and the SimpleDateFormat class that you tried to use, is notoriously troublesome. I recommend you forget about those classes and use java.time instead. The modern API is so much nicer to work with.
Except: it happens that you get a Date from a legacy API that you cannot change or don’t want to change just now. The best thing you can do with it is convert it to java.time.Instant and do any further operations from there:
Date oldfashoinedDate = // get from somewhere
LocalDate date = oldfashoinedDate.toInstant()
.atZone(ZoneId.of("Asia/Beirut"))
.toLocalDate();
Please substitute your desired time zone if it didn’t happen to be Asia/Beirut. Then proceed as above.
Link: Oracle tutorial: Date Time, explaining how to use java.time.
You can't format the Date itself. You can only get the formatted result in String. Use SimpleDateFormat as mentioned by others.
Moreover, most of the getter methods in Date are deprecated.
A date-time object is supposed to store the information about the date, time, timezone etc., not about the formatting. You can format a date-time object into a String with the pattern of your choice using date-time formatting API.
The date-time formatting API for the modern date-time types is in the package, java.time.format e.g. java.time.format.DateTimeFormatter, java.time.format.DateTimeFormatterBuilder etc.
The date-time formatting API for the legacy date-time types is in the package, java.text e.g. java.text.SimpleDateFormat, java.text.DateFormat etc.
Demo using modern API:
import java.time.LocalDate;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
ZonedDateTime zdt = ZonedDateTime.of(LocalDate.of(2012, Month.DECEMBER, 1).atStartOfDay(),
ZoneId.of("Europe/London"));
// Default format returned by Date#toString
System.out.println(zdt);
// Custom format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH);
String formattedDate = dtf.format(zdt);
System.out.println(formattedDate);
}
}
Output:
2012-12-01T00:00Z[Europe/London]
2012-12-01
Learn about the modern date-time API from Trail: Date Time.
Demo using legacy API:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
calendar.setTimeInMillis(0);
calendar.set(Calendar.YEAR, 2012);
calendar.set(Calendar.MONTH, 11);
calendar.set(Calendar.DAY_OF_MONTH, 1);
Date date = calendar.getTime();
// Default format returned by Date#toString
System.out.println(date);
// Custom format
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
String formattedDate = sdf.format(date);
System.out.println(formattedDate);
}
}
Output:
Sat Dec 01 00:00:00 GMT 2012
2012-12-01
Some more important points:
The java.util.Date object is not a real date-time object like the modern date-time types; rather, it represents the milliseconds from the Epoch of January 1, 1970. When you print an object of java.util.Date, its toString method returns the date-time calculated from this milliseconds value. Since java.util.Date does not have timezone information, it applies the timezone of your JVM and displays the same. If you need to print the date-time in a different timezone, you will need to set the timezone to SimpleDateFomrat and obtain the formatted string from it.
The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API.
For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7.
If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Millis for a given date are wrong using Date.parse(dateString)

I have a date string of 1/1/1970 8:00 AM
The correct millis should be 8 hours * 60 minutes per hour * 60000 milliseconds per minute = 28800000
However, using Date.parse(dateString) returns 50400000
What am I not understanding?
Edit
I originally tried using date.getTime();
Here's my original code:
SimpleDateFormat dateFmt = new SimpleDateFormat("MM/dd/yyyy h:mm a");
dateFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
StringBuilder sb = new StringBuilder();
sb.append(month).append("/");
sb.append(day).append("/");
sb.append(year).append(" ");
sb.append(pad(hour)).append(":");
sb.append(pad(minute)).append(" ");;
sb.append(ampm);
Date date = new Date();
date = dateFmt.parse(sb.toString());
date.getTime()
This is almost certainly the problem:
If no time zone is specified, the local time zone is assumed.
My guess is that you're in a time zone which was at UTC-6 at the Unix epoch, so 8am local time was 2pm UTC.
Then there's the more fundamental problem of you using deprecated methods when there are better alternative (SimpleDateFormat, which allows you to set the time zone) available. Methods are deprecated for a reason. You shouldn't just use deprecated methods regardless, otherwise you'll keep running into things like this.
In fact, you'd be better off using Joda Time if you possibly can - but at least stay away from the deprecated methods in Date.
Sample code:
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy h:mm aa", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
long millis = format.parse(text).getTime();
You may want to change dd/MM to MM/dd, depending on what format your dates are going to be in - we can't tell from "01/01". Note the explicit setting of both time zone and locale.
Its because of your local timezone. Use Simple date format with timezone as below to get your desired value against UTC timezone:
DateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
String dateS = "1/1/1970 8:00 AM";
format.setTimeZone(TimeZone.getTimeZone("UTC"));
format.setLenient(true);
Date date = format.parse(dateS);
System.out.println(date.getTime()); //<-- prints 28800000
or more compact:
DateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
format.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = format.parse("1/1/1970 8:00 AM");
System.out.println(date.getTime()); //<-- prints 28800000
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:
You do not need to form the string: You can use LocalDateTime#of to create an instance of LocalDateTime which can be converted into an Instant in order to get the number of milliseconds from the Unix epoch.
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
public class Main {
public static void main(String[] args) {
int year = 1970, month = 1, dayOfMonth = 1, hour = 8, minute = 0;
LocalDateTime ldt = LocalDateTime.of(year, month, dayOfMonth, hour, minute);
Instant instant = ldt.toInstant(ZoneOffset.UTC);
System.out.println(instant.toEpochMilli());
}
}
Output:
28800000
ONLINE DEMO
If you already have a date-time string in the given format:
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/u h:m a", Locale.ENGLISH);
String strDateTime = "1/1/1970 8:00 AM";
LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
Instant instant = ldt.toInstant(ZoneOffset.UTC);
System.out.println(instant.toEpochMilli());
}
}
Output:
28800000
ONLINE DEMO
An Instant represents an instantaneous point on the timeline in UTC.
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.

How to properly format the date?

The function shown below returns the date, e.g. "Sat Sep 8 00:00 PDT 2010". But I expected to get the date in the following format "yyyy-MM-dd HH:mm". What's wrong in this code?
String date = "2010-08-25";
String time = "00:00";
Also in one laptop the output for,e.g. 23:45 is 11:45. How can I define exactly the 24 format?
private static Date date(final String date,final String time) {
final Calendar calendar = Calendar.getInstance();
String[] ymd = date.split("-");
int year = Integer.parseInt(ymd[0]);
int month = Integer.parseInt(ymd[1]);
int day = Integer.parseInt(ymd[2]);
String[] hm = time.split(":");
int hour = Integer.parseInt(hm[0]);
int minute = Integer.parseInt(hm[1]);
calendar.set(Calendar.YEAR,year);
calendar.set(Calendar.MONTH,month);
calendar.set(Calendar.DAY_OF_MONTH,day);
calendar.set(Calendar.HOUR,hour);
calendar.set(Calendar.MINUTE,minute);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date d = calendar.getTime();
String dateString= dateFormat.format(d);
Date result = null;
try {
result = (Date)dateFormat.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
return result;
}
What's wrong in this code?
You seem to be expecting the returned Date object to know about the format you've parsed it from - it doesn't. It's just an instant in time. When you want a date in a particular format, you use SimpleDateFormat.format, it's as simple as that. (Well, or you use a better library such as Joda Time.)
Think of the Date value as being like an int - an int is just a number; you don't have "an int in hex" or "an int in decimal"... you make that decision when you want to format it. The same is true with Date.
(Likewise a Date isn't associated with a specific calendar, time zone or locale. It's just an instant in time.)
How did you print out the return result? If you simply use System.out.println(date("2010-08-25", "00:00") then you might get Sat Sep 8 00:00 PDT 2010 depending on your current date time format setting in your running machine. But well what you can do is:
Date d = date("2010-08-25", "00:00");
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm").format(d));
Just curious why do you bother with this whole process as you can simple get the result by concatenate your initial date and time string.
just use SimpleDateFormat class
See
date formatting java simpledateformat
The standard library does not support a formatted Date-Time object.
The function shown below returns the date, e.g. "Sat Sep 8 00:00 PDT
2010". But I expected to get the date in the following format
"yyyy-MM-dd HH:mm".
The standard Date-Time classes do not have any 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
About java.util.Date:
A java.util.Date object simply represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). 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(); // In your case, it will be Date date = date("2010-08-25", "00:00");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
// sdf.setTimeZone(TimeZone.getTimeZone("America/New_York")); // For a timezone-specific value
String strDate = sdf.format(date);
System.out.println(strDate);
Your function, Date date(String, String) is error-prone.
You can simply combine the date and time string with a separator and then use SimpleDateFormat to parse the combined string e.g. you can combine them with a whitespace character as the separator to use the same SimpleDateFormat shown above.
private static Date date(final String date, final String time) throws ParseException {
return sdf.parse(date + " " + time);
}
Note that using a separator is not a mandatory requirement e.g. you can do it as sdf.parse(date + time) but for this, you need to change the format of sdf to yyyy-MM-ddHH:mm which, although correct, may look confusing.
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class Main {
static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
public static void main(String[] args) throws ParseException {
Date date = date("2010-08-25", "00:00");
String strDate = sdf.format(date);
System.out.println(strDate);
}
private static Date date(final String date, final String time) throws ParseException {
return sdf.parse(date + " " + time);
}
}
Output:
2010-08-25 00:00
ONLINE DEMO
Switch to java.time API.
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*.
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.util.Locale;
public class Main {
public static void main(String[] args) {
LocalDateTime ldt = localDateTime("2010-08-25", "00:00");
// Default format i.e. the value of ldt.toString()
System.out.println(ldt);
// Custom format
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm", Locale.ENGLISH);
String strDate = dtf.format(ldt);
System.out.println(strDate);
}
private static LocalDateTime localDateTime(final String date, final String time) {
return LocalDateTime.of(LocalDate.parse(date), LocalTime.parse(time));
}
}
Output:
2010-08-25T00:00
2010-08-25 00:00
ONLINE DEMO
You must have noticed that I have not used DateTimeFormatter for parsing the String date and String time. It is because your date and time strings conform to the ISO 8601 standards. The modern Date-Time API is based on ISO 8601 and does not require using a DateTimeFormatter object explicitly as long as the Date-Time string conforms to the ISO 8601 standards.
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'm surprise you are getting different date outputs on the different computers. In theory, SimpleDateFormat pattern "H" is supposed to output the date in a 24h format. Do you get 11:45pm or 11:45am?
Although it should not affect the result, SimpleDateFormat and Calendar are Locale dependent, so you can try to specify the exact locale that you want to use (Locale.US) and see if that makes any difference.
As a final suggestion, if you want, you can also try to use the Joda-Time library (DateTime) to do the date manipulation instead. It makes it significantly easier working with date objects.
DateTime date = new DateTime( 1991, 10, 13, 23, 39, 0);
String dateString = new SimpleDateFormat("yyyy-MM-dd HH:mm").format( date.toDate());
DateTime newDate = DateTime.parse( dateString, DateTimeFormat.forPattern("yyyy-MM-dd HH:mm"));

Categories