I am using the code below on Mac OSX 10.10.2 and it's behaving strangely.
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class StringToDate {
public static void main(String[] args) throws Exception {
String dateInString = "23/Oct/2015";
DateFormat formatter = new SimpleDateFormat("dd/MMM/YYYY");
Date date = formatter.parse(dateInString);
System.out.println(date);
}
}
Output on Mac: Sun Dec 28 00:00:00 CST 2014
Output on Windows: Fri Oct 23 00:00:00 CDT 2015
Why is the Mac output wrong?
Y is for the week year. Use y for the year.
DateFormat formatter = new SimpleDateFormat("dd/MMM/yyyy");
Also, make sure the DateFormat's locale is the right one.
EDIT:
A Date has millisecond precision, so if you want nanosecond precision, you shouldn't use Date and SimpleDateFormat.
S is for milliseconds. Since you tell SimpleDateFormat that the last part of the string is milliseconds, it parses it as that: 545000000 milliseconds (i.e. a bit more than 6 days, which explains the difference between the input and the output).
To get an accurate result, to the millisecond, remove the last 6 characters of the string, and use the pattern "dd-MMM-yyyy-HH.mm.ss.SSS".
Related
I have the following Long variable holding epoch value in seconds, which I'm trying to convert into a Date.
val seconds = 1341855763000
val date = Date(TimeUnit.SECONDS.toMillis(seconds))
The output is way off than I expected. Where did I go wrong?
Actual: Wed Sep 19 05:26:40 GMT+05:30 44491
Expected: Monday July 9 11:12:43 GMT+05:30 2012
The output is way off than I expected. Where did I go wrong?
Actual: Wed Sep 19 05:26:40 GMT+05:30 44491
Expected: Monday July 9 11:12:43 GMT+05:30 2012
The value is already in milliseconds and by using TimeUnit.SECONDS.toMillis(seconds) you are wrongly multiplying it by 1000.
By using the modern date-time API:
import java.time.Instant;
public class Main {
public static void main(String[] args) {
Instant instant = Instant.ofEpochMilli(1341855763000L);
System.out.println(instant);
}
}
Output:
2012-07-09T17:42:43Z
By using legacy java.util.Date:
import java.util.Date;
public class Main {
public static void main(String[] args) {
System.out.println(new Date(1341855763000L));
}
}
Output:
Mon Jul 09 18:42:43 BST 2012
I recommend you switch from the outdated and error-prone java.util date-time API and SimpleDateFormat to the modern java.time date-time API and the corresponding formatting API (package, java.time.format). Learn more about the modern date-time API from Trail: Date Time.
The value you have is not in seconds but in milliseconds. Remove the "seconds to millis" conversion.
val milliSeconds = 1341855763000
val date = Date(milliSeconds)
Your value : 1341855763000 is not in seconds, it is in milliseconds.
The current timestamp is :
new Date().getTime() =>
1598612990351
Same number of digits than :
1341855763000
If you multiply 1341855763000 by 1000 (as you say), it gives the year :
44491 after JC :D
Have a good day
I think your time is actually in milliseconds. If I convert 1341855763000 using this website it gives me your expected time and this as well:
fun main() {
val millis = 1341855763000
val date = Date(millis)
println(date)
}
Alternatively, you can also use seconds:
fun main() {
val seconds = 1341855763L
val date = Date(TimeUnit.SECONDS.toMillis(seconds))
println(date)
}
Just divide by 1000.
Here, I attached my code and finally I get the date in string format (ex: 1). But I want it for date format (ex: 2)
Ex:1
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class Example{
public static void main(String []args){
java.util.Date date = new Date("Sat Dec 01 00:00:00 GMT 2017");
DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
String formatz = formatter.format(date);
System.out.println(formatz);
}}
The O/P is:
12/01/2017 // String so i cant able to parse it on my query.
Ex:2
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class Example{
public static void main(String []args){
java.util.Date date = new Date("Sat Dec 01 00:00:00 GMT 2017");
DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
String formatz = formatter.format(date);
Date d1 = formatter.parse(formatz);
System.out.println(d1);
}}
The O/P is:
Sat Dec 01 00:00:00 GMT 2017 // but i want 12/01/2017 (date format)
how can i resolve it.
try this:
System.out.println(formatter.format(d1));
First of all, I cannot more strongly advise against using the legacy java.util.Date and java.util.Calendar. You should always use the appropriate class in the java.time package instead.
Now, onto your question. Neither java.util.Date, nor any of the java.time.* classes, contain information about formatting. They contain simply enough information to represent the moment in time. If you want to use a different format from the default, you will need to use either a built-in formatter, or your own.
In your case, because formatz already has the format you want, you can simply print that instead.
I have a scenario where I need to convert a date time string from Timezone A(UTC) to Timezone B(EST).
Catch here is the JVM where this transformation is happening is Timezone C(HKT) Date Object.
So the code block is as follows:
String dateString="20141114213000";
dateString += " UTC";
String formatString ="yyyyMMddHHmmss";
SimpleDateFormat sdf = new SimpleDateFormat(formatString + " z");
Date localDate = sdf.parse(dateString);
System.out.println("Local Date::"+localDate); // Local Date::Sat Nov 15 05:30:00 HKT 2014
Calendar localCal = Calendar.getInstance();
localCal.setTime(localDate);
TimeZone estTimeZone = TimeZone.getTimeZone("America/New_York");
localCal.setTimeZone(estTimeZone);
sdf.setTimeZone(estTimeZone);
System.out.println(sdf.format(localCal.getTime()));//20141114163000 EST
System.out.println(localCal.getTime());//Sat Nov 15 05:30:00 HKT 2014
The output I am expecting is to be "Fri Nov 14 16:30:00 EST 2014" from the last statement, i.e., the final date object available should be in EST.
Please let know if anyone has info on this.
Update:
Just to make my request clear, output should be in Date object only.
The sample code and the output I printed is only for clearer explanation.
So basically String "20141114213000" which is a UTC Date String needs to be converted to EST Date Object and JVM where this transformation is happening is in HKT.
There seems to be notable issues with Java's Date and Time classes.
Lets use the popular Joda-Time - Java date and time API.
Simply download the newest stable release and add the jar files to your project's build path.
On a line-by-line basis, I have commented out your code and rewritten the Joda Time alternative. This way you can understand how I transitioned your existing code to the Joda Time API.
import java.text.ParseException;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
public class JodaTimeTransition {
public static void main(String[] args) throws ParseException {
String dateString="20141114213000";
dateString += " UTC";
/*new*/
String formatString = "yyyyMMddHHmmss z";
// String formatString ="yyyyMMddHHmmss";
/*new*/
DateTimeFormatter dtf = DateTimeFormat.forPattern(formatString);
// SimpleDateFormat sdf = new SimpleDateFormat(formatString + " z");
/* new - Create localDate using JodaTime DateTime class */
DateTime localDate = DateTime.parse(dateString, dtf);
// Date localDate = sdf.parse(dateString);
/* new - convert time to MST, since it is currently UTC*/
localDate = localDate.toDateTime(DateTimeZone.forID("America/Denver"));
/* new - print out <local date> using specified format.*/
System.out.println("Local Date::" + localDate.toString("EEE MMM dd HH:mm:ss z yyyy"));
/* Where did you get the local date mentioned at comments of line below? */
// System.out.println("Local Date::"+localDate); // Local Date::Sat Nov 15 05:30:00 HKT 2014
/* new - Get reference to current date/time as <localCal>
* (This step can be omitted, and the previous localDate variable can be used)
*/
DateTime localCal = DateTime.now();
// Calendar localCal = Calendar.getInstance();
/* new - Set <localCal> to <localDate> */
localCal = localDate;
// localCal.setTime(localDate);
/* new - Create new EST time zone*/
DateTimeZone estTimeZone= DateTimeZone.forID("America/New_York");
// TimeZone estTimeZone = TimeZone.getTimeZone("America/New_York");
/* new - set <localCal> time zone from MST to EST */
localCal = localCal.toDateTime(estTimeZone);
// localCal.setTimeZone(estTimeZone);
// sdf.setTimeZone(estTimeZone);
/* new - print <localCal> as new EST time zone */
System.out.println(localCal.toString("yyyyMMddHHmmss z"));
// System.out.println(sdf.format(localCal.getTime()));//20141114163000 EST
/* new - print in desired format: Fri Nov 14 16:30:00 EST 2014 */
System.out.println(localCal.toString("EEE MMM dd HH:mm:ss z yyyy"));
// System.out.println(localCal.getTime());//Sat Nov 15 05:30:00 HKT 2014
}
}
This is actually very straightforward (no need for Joda time, not that it isn't a great library), you just need to set the TimeZone on the SimpleDateFormat. Use the source TimeZone when you parse, then the destination TimeZone when you format (and you don't need the intermediate Calendar).
UPDATE:
Date's don't have TimeZones. If you want something with a TimeZone (other than a String), then you will need a Calendar. Your current code is mostly correct except that you haven't set the source TimeZone on the SimpleDateFormat before parsing.
Update
After some discussion in the comments, it seems now clear that you should not rely on java.util.Date for time zones at all. The trick sketched below (my original answer) will probably work, but it is not the right thing to do. Switch to something which supports time zones (java.util.Calendar for instance), but better use JodaTime.
Warning: this is a trick which may (or may not) work for Sun's implementation of java.util.Date whose internal structures are initialized with a time zone.
Try setting the default time zone with TimeZone.setDefault(...) first.
Your last call:
System.out.println(localCal.getTime());
Is actually:
System.out.println(new Date(localCal.getTimeInMillis()).toString());
So setting any time zone info on the calendar is pointless.
Date.toString(), however first does an internal normalization on the date and uses the static TimeZone.getDefaultRef(). This should give you the default time zone - which you can (normally) set via TimeZone.setDefailt(...).
And by all means use JodaTime.
This caused a Y2K-style bug in my software if you can imagine. Strange thing is the off-by-one year calculation only occurs for two days in the year, which I'm less sure how to troubleshoot.
The output:
03-Jan-2013
02-Jan-2013
01-Jan-2013
31-Dec-2013 ** strange
30-Dec-2013 ** strange
29-Dec-2012
28-Dec-2012
27-Dec-2012
26-Dec-2012
25-Dec-2012
I am not sure which part of the Java date utilities could cause such an error.
The code (since the test is so small I included a complete working program):
import java.util.Calendar;
import java.util.Date;
import java.text.SimpleDateFormat;
public class DateT {
private static String getFormattedBackscanStartTime(int days) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-YYYY");
Calendar workingDate = Calendar.getInstance();
workingDate.add(Calendar.DATE, -1 * days);
String formattedStartTime = dateFormat.format(workingDate.getTime());
return formattedStartTime;
}
public static void main(String args[]) {
for(int i = 35; i < 45; i++) {
System.out.println(getFormattedBackscanStartTime(i));
}
}
}
This is the problem:
"dd-MMM-YYYY"
YYYY is the week-year, not the calendar year. You want yyyy instead.
The last two days of calendar year 2012 were in the first week of week-year 2013. You should normally only use the week year in conjunction with the "week of year" specifier (w).
I am assuming you are using java 1.7.
The code snippet above will not work with java 1.6 as SimpleDateFormat("dd-MMM-YYYY") will raise an java.lang.IllegalArgumentException (YYYY is not available in java 1.6)
You need to use yyyy instead of YYYY.
Y -> week-year
y -> year
here
EDIT
Works great with yyyy:
$ java DateT
03-Jan-2013
02-Jan-2013
01-Jan-2013
31-Dec-2012
30-Dec-2012
29-Dec-2012
28-Dec-2012
27-Dec-2012
26-Dec-2012
25-Dec-2012
The problem lies in your date format string - year should be yyyy not YYYY.
If you print the value of workingDate.getTime() in each iteration of the loop, you'll see it has the expected values:
Thu Jan 03 11:19:33 EST 2013
Wed Jan 02 11:19:33 EST 2013
Tue Jan 01 11:19:33 EST 2013
Mon Dec 31 11:19:33 EST 2012
Sun Dec 30 11:19:33 EST 2012
Sat Dec 29 11:19:33 EST 2012
Fri Dec 28 11:19:33 EST 2012
Thu Dec 27 11:19:33 EST 2012
Wed Dec 26 11:19:33 EST 2012
Tue Dec 25 11:19:33 EST 2012
Therefore the problem lies in the SimpleDateFormat usage.
For the sake of completeness, here’s the modern answer using LocalDate (as recommended by Basil Bourque in a comment).
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class DateT {
private static DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("dd-MMM-uuuu", Locale.US);
private static String getFormattedBackscanStartTime(int days) {
return LocalDate.now(ZoneId.systemDefault()).minusDays(days).format(dateFormatter);
}
public static void main(String args[]) {
for(int i = 155; i < 165; i++) {
System.out.println(getFormattedBackscanStartTime(i));
}
}
}
Running this today I got
04-Jan-2017
03-Jan-2017
02-Jan-2017
01-Jan-2017
31-Dec-2016
30-Dec-2016
29-Dec-2016
28-Dec-2016
27-Dec-2016
26-Dec-2016
A few things to note:
Give an explicit locale to your formatter to control the langauge of your output. Even if you just pass Locale.getDefault() you are telling the reader that you have thought about locale and made a decision.
Similarly give an explicit time zone to LocalDate.now() to tell the reader you’ve made a decision (for example ZoneId.of("America/New_York") for a specific time zone; ZoneId.systemDefault() for the JVM’s current time zone setting).
I find the code simpler and more straightforward than the code using the oldfashioned Calendar class. This is typical for the newer classes.
I have used uuuu for year. yyyy (lowercase) works too, there will only be a difference for years before the common era (AKA BC).
You need to use lower case y for the year. Try this:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
I have a website which supplies date in 2 formats: 28th June 2009 or June 2009.
Now I would like to convert both of these into the same format yyyy-mm-dd hh:mm:ss using MySQL and Java.
SimpleDateFormat gives an error: "Unparsable Date". What's the solution?
What about June 2009 as you can not say its a date you need to make it a date by adding a day in this month-year format. Ex.. add first day of month here and make it 1 June 2009 then parse it in desired format.
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test {
public static void main(String[] args) throws IOException, ParseException
{
String dateStr = "28 June 2009";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println(sdf.format(new Date(dateStr)));
}
}