Why Calendar and SimpleDateFormat are showing a bad date? - java

I try to parse a date from a string but when I print it, it shows a bad date. My code:
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.text.SimpleDateFormat;
public class Main {
public static void main(String args[]) {
String some_date = "2017-12-31";
Calendar cal_aux = GregorianCalendar.getInstance();
System.out.println("set calendar: " + Integer.parseInt(some_date.substring(0, 4))
+ Integer.parseInt(some_date.substring(5, 7))
+ Integer.parseInt(some_date.substring(8, 10)));
cal_aux.set(Integer.parseInt(some_date.substring(0, 4)),
Integer.parseInt(some_date.substring(5, 7)),
Integer.parseInt(some_date.substring(8, 10)));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println("sdf calendar: " + sdf.format(cal_aux.getTime()));
}
}
Console output:
set calendar: 20171231
sdf calendar: 2018-01-31 12:51:02
Why when I use the simple date format I'm getting 2018 instead of 2017?

Avoid the legacy date-time classes now supplanted by java.time classes. The problematic legacy classes have many design faults. One such fault is counting months as 0-11 rather than 1-12. This crazy counting is breaking your code.
Do not manipulate date-time values as strings. Use objects.
For that date-only value use LocalDate.
LocalDate ld = LocalDate.parse( "2017-12-31" ) ; // Or LocalDate.now() for today's date.
Generate a String by using a DateTimeFormatter.
String output = ld.format( DateTimeFormatter.BASIC_ISO_DATE ) ;
20171231
Assign a time-of-day if desired.
LocalTime lt = LocalTime.of( 6 , 15 ) ;
LocalDateTime ltd = LocalDateTime.of( ld , lt ) ;
Apply a time zone if you want an actual moment, a specific point on the timeline.
ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

First, you set wrong date because the month range is 0-11. When you set 12 in month field, is january 2018 instead december 2017.
Second, you can simplify your program parsing the input string to formatted date and parsing this date to output formatted string. Here is an example:
String input = "20171231";
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyyMMdd");
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
System.out.println(outputFormat.format(inputFormat.parse(input)));
} catch (ParseException e) {
// Log error
}

Related

Change time zone of exesting date in Java [duplicate]

This question already has answers here:
How to set time zone of a java.util.Date?
(12 answers)
Closed 7 months ago.
I want to change the time zone of given date. I use this code, but i dont have the good result.
My input is "2020-06-16 14:00:00" time in Europe/Paris, and I wnat to change it to UTC, that means I want to get "2020-06-16 12:00:00", but I get initial result "2020-06-16 14:00:00".
try {
// Calendar calParis = Calendar.getInstance();
String heure = "1400";
Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2020-06-16");
String hour = heure.substring(0, heure.length() - 2);
String minute = heure.substring(heure.length() - 2);
Calendar cal = Calendar.getInstance();
String datenew = "2020-06-16" + " " + hour + ":" + minute + ":00";
SimpleDateFormat sdfDatenew = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
Date thisDate = sdfDatenew.parse(datenew);
cal.setTime(thisDate);
cal.setTimeZone(TimeZone.getTimeZone("Europe/UTC"));
SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
String dateISO = null;
dateISO = sdfDate.format(cal.getTime());
System.out.println("Time in ISO: " + dateISO);
} catch (Exception ex) {
}
Here you go:
This way you can get your dates and time in Java-7 format.
public static void main(String[] args) throws ParseException {
String heure = "1400";
Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2020-06-16");
String hour = heure.substring(0, heure.length() - 2);
String minute = heure.substring(heure.length() - 2);
String datenew = "2020-06-16" + " " + hour + ":" + minute + ":00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Calendar calendar = Calendar.getInstance();
Date thisDate = sdf.parse(datenew);
calendar.setTime(thisDate);
sdf.setTimeZone(TimeZone.getTimeZone("PDT"));
System.out.println(sdf.format(calendar.getTime())); // prints 2020-06-16 12:00:00
sdf.setTimeZone(TimeZone.getDefault());
System.out.println(sdf.format(calendar.getTime())); // prints 2020-06-16 14:00:00
}
tl;dr
LocalDateTime
.parse(
"2020-06-16 14:00:00"
.replace( " " , "T" )
)
.atZone(
ZoneId.of( "Europe/Paris" )
)
.toInstant()
.atOffset( ZoneOffset.UTC )
.format(
DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" )
)
See this code run live at IdeOne.com.
2020-06-16 12:00:00
java.time
The modern solution uses java.time classes.
Your input string lacks a time zone or offset. So parse as a LocalDateTime object.
LocalDateTime ldt = LocalDateTime.parse( "2020-06-16 14:00:00".replace( " " , "T" ) ) ;
You say with certainty that this string represents a moment as seen in Paris France time zone.
ZoneId zParis = ZoneId.of( "Europe/Paris" ) ;
ZonedDateTime zdt = ldt.atZone( zParis ) ;
Adjust from there to your target time zone. You happen to want UTC, so just extract an Instant.
Instant instant = zdt.toInstant() ;
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*, released in March 2014 as part of Java SE 8 standard library.
The answer by Basil Bourque is correct but I would not use String replacement when DateTimeFormatter is capable enough to address this and much more.
Demo:
import java.time.LocalDateTime;
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) {
String input = "2020-06-16 14:00:00";
DateTimeFormatter dtfInput = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(input, dtfInput);
ZonedDateTime zdtParis = ldt.atZone(ZoneId.of("Europe/Paris"));
ZonedDateTime zdtUtc = zdtParis.withZoneSameInstant(ZoneId.of("Etc/UTC"));
// Default format
System.out.println(zdtUtc);
// Custom format
DateTimeFormatter dtfOutput = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
String output = dtfOutput.format(zdtUtc);
System.out.println(output);
}
}
Output:
2020-06-16T12:00Z[Etc/UTC]
2020-06-16 12:00:00
ONLINE DEMO
All in a single statement:
System.out.println(
LocalDateTime
.parse("2020-06-16 14:00:00", DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH))
.atZone(ZoneId.of("Europe/Paris"))
.withZoneSameInstant(ZoneId.of("Etc/UTC"))
.format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH))
);
ONLINE DEMO
Some important notes:
You can use a single pattern, uuuu-MM-dd HH:mm:ss for both of your input and output strings but I prefer using u-M-d H:m:s for parsing because uuuu-MM-dd HH:mm:ss will fail if you have a year in two digits, a month in single digit, a day-of-month in single digit etc. For parsing, a single u can cater to both, two-digit and four-digit year representation. Similarly, a single M can cater to both one-digit and two-digit month. Similar is the case with other symbols.
Here, you can use y instead of u but I prefer u to y.
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 Set to 01

How can i put 01 in date but not the exact date today in SimpleDateFormat
when I use
SimpleDateFormat day= new SimpleDateFormat("dd");
the it gives me the exact date today.. so how can i put my specific date for this
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
String NOW = (sdf.format(new java.util.Date()));
SimpleDateFormat month = new SimpleDateFormat("MM");
String MONTH = (month.format(new java.util.Date()));
SimpleDateFormat year = new SimpleDateFormat("yyyy");
String YEAR = (year.format(new java.util.Date()));
String PAST = ((MONTH)+"-"+(1)+"-"+(YEAR));
the ((MONTH)+"-"+(1)+"-"+(YEAR)); returns 1 but it should be 01 but when I run it it turn into 1 only
tl;dr
YearMonth
.now(
ZoneId.of( "America/Montreal" )
)
.atDay( 1 )
.format(
DateTimeFormatter.ofPattern( "MM-dd-uuuu" )
)
java.time
The modern approach uses the java.time classes. Never use the terrible legacy classes such as Calendar and SimpleDateFormat.
Get the current year and month.
YearMonth ym = YearMonth.now() ;
Get the first day of that month.
LocalDate ld = ym.atDay( 1 ) ;
Specify you desired formatting pattern.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM-dd-uuuu" ) ;
String output = ld.format( f ) ;
If you want to create a Date object out of a string representation of a date, then you could use parse(String source) method of SimpleDateFormat.
For example:
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
Date date = sdf.parse("09-01-2018");
Then, as you previosly showed, if you want to format a Date object to a string in a specific format, just invoke:
sdf.format(date).
Note: Be aware that sdf.parse(String source) could throw a ParseException if the string is not a valid date.

Converting calendar to date in dd-MMM-yyyy format

I am trying to add 17 days to 10-APR-2014 and convert the date to dd-MMM-yyyy format, but I am getting Sun Apr 27 00:00:00 GMT+05:30 2014.
Here is my code:
import java.util.*;
import java.text.*;
public class HelloWorld{
public static void main(String []args){
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
Calendar c = Calendar.getInstance();
c.setTime(new Date());
c.add(Calendar.DATE, 17);
String output = sdf.format(c.getTime());
System.out.println(output);
System.out.print(new SimpleDateFormat("dd-MMM-yyyy").parse(output));
}
}
How can I make the output be 27-Apr-2014?
You are printing a Date parsed from a String formatted from the calendar date.
Instead, print the formatted calendar date:
System.out.print(new SimpleDateFormat("dd-MMM-yyyy").format(c.getTime()));
If displaying and using the dates is disjunct, do this:
Date date; // from Calendar or wherever
String str = new SimpleDateFormat("dd-MMM-yyyy").format(date));
// display str
Then when you want to do something with a selected date:
String selection;
Date date = new SimpleDateFormat("dd-MMM-yyyy").parse(selection));
// do something with date
The answer by Bohemian is correct. Here I present an alternative solution.
Avoid j.u.Date
The java.util.Date and .Calendar classes bundled with Java are notoriously troublesome. Avoid them. Use either Joda-Time or the new java.time package in Java 8.
Date-Only
If you need only a date, without any time component, both Joda-Time and java.time offer a LocalDate class.
Time Zone
Even for a date-only, you still need a time zone to get "today". At any moment the date may vary ±1 depending on your location on the globe. If you do not specify a time zone, the JVM's default time zone will be applied.
Example Code
Here is some example code in Joda-Time 2.3.
Determine "today" based on some time zone. Add seventeen days.
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
LocalDate today = new LocalDate( timeZone );
LocalDate seventeenDaysLater = today.plusDays( 17 );
Generate a String representation of the date-time value…
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd-MMM-yyyy" );
String output = formatter.print( seventeenDaysLater );
Dump to console…
System.out.println( "today: " + today );
System.out.println( "seventeenDaysLater: " + seventeenDaysLater );
System.out.println( "output: " + output );
When run…
today: 2014-04-21
seventeenDaysLater: 2014-05-08
output: 08-May-2014

converting UTC date string to local date string inspecific format

I have a UTC date in string
String utcDate = "2014-03-05 07:09:07.0";
I want to convert it to local date string of format DD-MMM-YYYY hh:mm a
eg: 5-Mar-2014 12:39 PM from UTC date 2014-03-05 07:09:07.0
How this can be achieved using simple java or joda API
Very easy to achieve with default functionality. I hope the local data is for display only.
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
parser.setTimeZone(TimeZone.getTimeZone("UTC"));
Date parsed = parser.parse(utcDate);
SimpleDateFormat formatter = new SimpleDateFormat("d-MMM-yyyy hh:mm a");
System.out.println(formatter.format(parsed));
The java.util.Date and .Calendar classes are notoriously troublesome. Avoid them. Instead use either Joda-Time library or the new java.time package in bundled with Java 8.
If you use the ISO 8601 format of strings, you can pass the string directly to a Joda-Time DateTime constructor. Your input string is close, but the space in the middle should be a T.
Some example code using the Joda-Time 2.3 library.
String input = "2014-03-05 07:09:07.0";
String inputModified = input.replace( " ", "T" );
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" );
DateTime dateTimeUtc = new DateTime( inputModified, DateTimeZone.UTC );
DateTime dateTimeParis = dateTimeUTC.toZone( timeZone );
String outputFrance = DateTimeFormat.forPattern( "FF" ).withLocale(Locale.FRANCE).print( dateTimeParis );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "d-MMM-yyyy hh:mm a" ).withLocale( Locale.US );
String outputParisCustom = formatter.print( dateTimeParis );
Below code will help you to convert your UTC to IST or any other timezone. You need to pay attention to the timezone that you want to use with SimpleDateFormat.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class ConvertTimeZone {
public static void main(String args[]) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sdf.parse("2014-03-05 07:09:07");
System.out.println("time in UTC " +sdf.format(date));
sdf.setTimeZone(TimeZone.getTimeZone("IST"));
System.out.println("Time in IST is " + sdf.format(date));
}
}

Display current time in 12 hour format with AM/PM

Currently the time displayed as 13:35 PM
However I want to display as 12 hour format with AM/PM, i.e 1:35 PM instead of 13:35 PM
The current code is as below
private static final int FOR_HOURS = 3600000;
private static final int FOR_MIN = 60000;
public String getTime(final Model model) {
SimpleDateFormat formatDate = new SimpleDateFormat("HH:mm a");
formatDate.setTimeZone(userContext.getUser().getTimeZone());
model.addAttribute("userCurrentTime", formatDate.format(new Date()));
final String offsetHours = String.format("%+03d:%02d", userContext.getUser().getTimeZone().getRawOffset()
/ FOR_HOURS, Math.abs(userContext.getUser().getTimeZone().getRawOffset() % FOR_HOURS / FOR_MIN));
model.addAttribute("offsetHours",
offsetHours + " " + userContext.getUser().getTimeZone().getDisplayName(Locale.ROOT));
return "systemclock";
}
Easiest way to get it by using date pattern - h:mm a, where
h - Hour in am/pm (1-12)
m - Minute in hour
a - Am/pm marker
Code snippet :
DateFormat dateFormat = new SimpleDateFormat("hh:mm a");
Read more on documentation - SimpleDateFormat java 7
Use this SimpleDateFormat formatDate = new SimpleDateFormat("hh:mm a");
Java docs for SimpleDateFormat
use "hh:mm a" instead of "HH:mm a". Here hh for 12 hour format and HH for 24 hour format.
Live Demo
SimpleDateFormat formatDate = new SimpleDateFormat("hh:mm:ss a");
h is used for AM/PM times (1-12).
H is used for 24 hour times (1-24).
a is the AM/PM marker
m is minute in hour
Note: Two h's will print a leading zero: 01:13 PM. One h will print without the leading zero: 1:13 PM.
Looks like basically everyone beat me to it already, but I digress
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yy hh.mm.ss.S aa");
String formattedDate = dateFormat.format(new Date()).toString();
System.out.println(formattedDate);
Output:
11-Sep-13 12.25.15.375 PM
// hh:mm will print hours in 12hrs clock and mins (e.g. 02:30)
System.out.println(DateTimeFormatter.ofPattern("hh:mm").format(LocalTime.now()));
// HH:mm will print hours in 24hrs clock and mins (e.g. 14:30)
System.out.println(DateTimeFormatter.ofPattern("HH:mm").format(LocalTime.now()));
// hh:mm a will print hours in 12hrs clock, mins and AM/PM (e.g. 02:30 PM)
System.out.println(DateTimeFormatter.ofPattern("hh:mm a").format(LocalTime.now()));
Using Java 8:
LocalTime localTime = LocalTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm a");
System.out.println(localTime.format(dateTimeFormatter));
The output is in AM/PM Format.
Sample output: 3:00 PM
tl;dr
Let the modern java.time classes of JSR 310 automatically generate localized text, rather than hard-coding 12-hour clock and AM/PM.
LocalTime // Represent a time-of-day, without date, without time zone or offset-from-UTC.
.now( // Capture the current time-of-day as seen in a particular time zone.
ZoneId.of( "Africa/Casablanca" )
) // Returns a `LocalTime` object.
.format( // Generate text representing the value in our `LocalTime` object.
DateTimeFormatter // Class responsible for generating text representing the value of a java.time object.
.ofLocalizedTime( // Automatically localize the text being generated.
FormatStyle.SHORT // Specify how long or abbreviated the generated text should be.
) // Returns a `DateTimeFormatter` object.
.withLocale( Locale.US ) // Specifies a particular locale for the `DateTimeFormatter` rather than rely on the JVM’s current default locale. Returns another separate `DateTimeFormatter` object rather than altering the first, per immutable objects pattern.
) // Returns a `String` object.
10:31 AM
Automatically localize
Rather than insisting on 12-hour clock with AM/PM, you may want to let java.time automatically localize for you. Call DateTimeFormatter.ofLocalizedTime.
To localize, specify:
FormatStyle to determine how long or abbreviated should the string be.
Locale to determine:
The human language for translation of name of day, name of month, and such.
The cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.
Here we get the current time-of-day as seen in a particular time zone. Then we generate text to represent that time. We localize to French language in Canada culture, then English language in US culture.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
LocalTime localTime = LocalTime.now( z ) ;
// Québec
Locale locale_fr_CA = Locale.CANADA_FRENCH ; // Or `Locale.US`, and so on.
DateTimeFormatter formatterQuébec = DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT ).withLocale( locale_fr_CA ) ;
String outputQuébec = localTime.format( formatterQuébec ) ;
System.out.println( outputQuébec ) ;
// US
Locale locale_en_US = Locale.US ;
DateTimeFormatter formatterUS = DateTimeFormatter.ofLocalizedTime( FormatStyle.SHORT ).withLocale( locale_en_US ) ;
String outputUS = localTime.format( formatterUS ) ;
System.out.println( outputUS ) ;
See this code run live at IdeOne.com.
10 h 31
10:31 AM
If you want current time with AM, PM in Android use
String time = new SimpleDateFormat("hh : mm a", Locale.getDefault()).format(Calendar.getInstance().getTime());
If you want current time with am, pm
String time = new SimpleDateFormat("hh : mm a", Locale.getDefault()).format(Calendar.getInstance().getTime()).toLowerCase();
OR
From API level 26
LocalTime localTime = LocalTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("hh:mm a");
String time = localTime.format(dateTimeFormatter);
Just replace below statement and it will work.
SimpleDateFormat formatDate = new SimpleDateFormat("hh:mm a");
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm a");
This will display the date and time
//To get Filename + date and time
SimpleDateFormat f = new SimpleDateFormat("MMM");
SimpleDateFormat f1 = new SimpleDateFormat("dd");
SimpleDateFormat f2 = new SimpleDateFormat("a");
int h;
if(Calendar.getInstance().get(Calendar.HOUR)==0)
h=12;
else
h=Calendar.getInstance().get(Calendar.HOUR)
String filename="TestReport"+f1.format(new Date())+f.format(new Date())+h+f2.format(new Date())+".txt";
The Output Like:TestReport27Apr3PM.txt
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.util.Date;
public class Main {
public static void main(String [] args){
try {
DateFormat parseFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm a");
String sDate = "22-01-2019 13:35 PM";
Date date = parseFormat.parse(sDate);
SimpleDateFormat displayFormat = new SimpleDateFormat("dd-MM-yyyy hh:mm a");
sDate = displayFormat.format(date);
System.out.println("The required format : " + sDate);
} catch (Exception e) {}
}
}
- Using java 8
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class Main
{
public static void main(String[] args)
{
String pattern = "hh:mm:ss a";
//1. LocalTime
LocalTime now = LocalTime.now();
System.out.println(now.format(DateTimeFormatter.ofPattern(pattern)));
//2. LocalDateTime
LocalDateTime nowTime = LocalDateTime.now();
System.out.println(nowTime.format(DateTimeFormatter.ofPattern(pattern)));
}
}
To put your current mobile date and time format in
Feb 9, 2018 10:36:59 PM
Date date = new Date();
String stringDate = DateFormat.getDateTimeInstance().format(date);
you can show it to your Activity, Fragment, CardView, ListView anywhere by using TextView
` TextView mDateTime;
mDateTime=findViewById(R.id.Your_TextViewId_Of_XML);
Date date = new Date();
String mStringDate = DateFormat.getDateTimeInstance().format(date);
mDateTime.setText("My Device Current Date and Time is:"+date);
`
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss a");
("hh:mm:ss a") >>> Here if we don't use 'a' then 24hours will be appeared. so if we want to AM/PM in your time just add this format. if any confusion please let me know.

Categories

Resources