I have a requirement in project
to Convert 24 hours format to 12 hours format
for example
if it is 17:12:01 it should be converted to 05:12:01
You can use a SimpleDateFormat http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html to format it.
Date date = new Date(yourdate);
// format however you see fit
SimpleDateFormat format = new SimpleDateFormat("hh:mm:ss");
String formatted = format.format(date);
As suggested by Software Monkey, also use a SimpleDateFormat to parse your 24hr date if you don't already have it in millis.
Use two SimpleDateFormat objects - one to parse and the other to format the time.
Note also that 05:12:01 is not technically a 12 hour time (rather it appears to be an AM 24 hour time, given the lead 0 on the hour and the lack of a meridian designation). You probably want 5:12:01 PM.
It is possible that a 12 hour SimpleDateFormat will correctly parse a 24 hour time, provided that it is configured for lenient parsing. Just saying, so perhaps you need only one SimpleDateFormat.
Related
I am trying to update my existing elasticsearch springboot project and as the source code is fairly old it still uses joda time. Now I have to upgrade all the functions of Joda time to java time. Now in the project We use Date Time of Joda Time
Code Sample for Joda Time
DateTime target = new DateTime(String targetDate, UTC);
We use this function currently in our code to convert a String to Date.
Using this function the String
2022-10-01T00:00:00.000
gets converted to
2022-10-01T00:00:00.000Z
I am trying to replicate the same in java time.
I tried to parse the targetDate using OffsetDateTime and ZonedDateTime but both gave me errors.
Text '2022-10-01T00:00:00.0000' could not be parsed at index 24
After some attempts I was able to move forward by using LocalDateTime
LocalDateTime target = LocalDateTime.parse(String targetDate);
Which was able to parse the String but the format was not correct the format I got was
2022-10-01T00:00Z
I also tried using the formatter with LocalDateTime
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSS'Z'");
LocalDateTime target= LocalDateTime.parse(targetDate,formatter);
But This Still gave me the Error
Text '2022-10-01T00:00:00.0000' could not be parsed at index 24
Now I am a bit confused regarding this.
Any help is appreciated.
And Please correct me if my way of asking question or formatting is wrong at any point still new to this.
Regards.
EDIT: Sorry for the confusion but as pointed out I should have mentioned that I want the returned value as the java.time datetime object and not a String so that I can further perform some logic on it. Sorry for this.
Thanks and Regards
The String "2022-10-01T00:00:00.000" can be parsed to a LocalDateTime because it only consists of year, month of year, day of month, hour of day, minute of hour, second of minute and fractions of second.
Your desired output String "2022-10-01T00:00:00.000Z" represents the same values plus an offset, the Z for Zulu time, which basically means UTC.
If you want to add an offset to the input String with java.time, you can parse it to a LocalDateTime and then append the desired offset, which results in an OffsetDateTime. You can print that in a desired format using a DateTimeFormatter, either use a prebuilt one or define one yourself.
Here's a small example:
public static void main(String[] args) {
// input value
String dateTime = "2022-10-01T00:00:00.000";
// parse it and append an offset
OffsetDateTime odt = LocalDateTime.parse(dateTime).atOffset(ZoneOffset.UTC);
// define a formatter that formats as desired
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX");
// and print the OffsetDateTime using that formatter
System.out.println(odt.format(dtf));
}
Output:
2022-10-01T00:00:00.000Z
Clarification update:
There is just a single instance OffsetDateTime in my example with the following values:
year (2022)
month of year (10)
day of month (1)
hour of day (0)
minute of hour (0)
second of minute (0)
franctions of second (0)
offset (UTC / +00:00)
This instance of OffsetDateTime can be used for calculations (e.g. add/subtract days, months or other units) and it can be formatted as String. It also has a toString() method we don't have under control, but is used if you don't explicitly format it.
The following lines (first one is the last of my example above) show some different usages:
// print formatted by the DateTimeFormatter from the above example
System.out.println(odt.format(dtf));
// print the object directly, implicitly using its toString()
System.out.println(odt);
// print formatted by a prebuilt DateTimeFormatter (several are available)
System.out.println(odt.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
// print with a formatter that uses locale dependant expressions like month names
System.out.println(odt.format(
DateTimeFormatter.ofPattern("EEEE, MMM dd HH:mm:ss xxx",
Locale.ENGLISH)));
the last one also uses a different representation for UTC: instead of Z it shows the offset in hours and minutes.
Output:
2022-10-01T00:00:00.000Z
2022-10-01T00:00Z
2022-10-01T00:00:00Z
Saturday, Oct 01 00:00:00 +00:00
I am struggling with this ..
I have an input string - like this: 2021-10-13 11:33:16.000-04
Using Java.
I need to get a Date object from it.
which formatting pattern can I use ?
I try with these
SimpleDateFormat inFormatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.SSS'-'ZZ");
and
SimpleDateFormat inFormatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.SSSZZ");
and I keep getting
java.text.ParseException: Unparseable date: "2021-10-13 11:33:16.000-04"
at java.base/java.text.DateFormat.parse(DateFormat.java:396)
at com.dima.tests.DatesConversions.main(DatesConversions.java:24)
Please, help !!
Don't use Date as it is outdated. Use the classes in the java.time
OffsetDateTime odt = OffsetDateTime.parse(str,
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSX"));
System.out.println(odt);
Prints
2021-10-13T11:33:16-04:00
java.time
Even though you need to give an old-fashionede Date object to a legacy API beyond your control, I still recommend that you use java.time, the modern Java date and time API, in your own code. The final conversion to Date is pretty straight-forward.
I’d use this formatter for maximum reuse of existing formatters:
private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE)
.appendLiteral(' ')
.append(DateTimeFormatter.ISO_LOCAL_TIME)
.appendOffset("+HHmm", "+00")
.toFormatter(Locale.ROOT);
Then we parse and convert like this:
String input = "2021-10-13 11:33:16.000-04";
OffsetDateTime dateTime = OffsetDateTime.parse(input, PARSER);
System.out.println(dateTime);
Instant i = dateTime.toInstant();
Date oldfashionedDate = Date.from(i);
System.out.println(oldfashionedDate);
Output in my time zone, Europe/Copenhagen:
2021-10-13T11:33:16-04:00
Wed Oct 13 17:33:16 CEST 2021
Denmark is at offset +02:00 at this time of year, so 6 hours ahead of the UTC offset -04 from your string. Therefore Date.toString() confusingly prints a clock hour that is 6 hours ahead of the original time of day.
Note: if your forward service accepts anything else than an old-fashioned Date, you should not be using that class. For example, if a String is required, the OffsetDateTime that we got can be formatted into a new string using a second DateTimeFormatter (or in lucky cases, its toString method).
What went wrong in your code?
First, a UTC offset can have positive or negative sign. Instead of -04 you could have had for example +09. Formatters are designed for to take the sign, + or -, as part of the offset. Therefore hardcoding the minus sign as a literal, as in your first attempt, is bound to fail. In your second attempt, yyyy-MM-dd HH:mm:ss.SSSZZ, you are already closer. However, ZZ is for an offset with sign and four digits (like +0530 or -0400; hour and minute), so does not work for a two-digit offset like -04. Your SimpleDateFormat expected more digits where your string ended and therefore threw the exception that you saw.
Link
Oracle tutorial: Date Time explaining how to use java.time.
Since you are using ISO 8601 time zone timezone, you have the use the below pattern.
SimpleDateFormat inFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSX");
And then, to get the date:
Date date = inFormatter.parse("2021-10-13 11:33:16.000-04");
Always check the documentation.
I tried to remove minute from given time, but some how it is converting time to my local time zone
String timeStamp="20180623 05:58:15" ;
dateFormat inputFormatter = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
Date date = inputFormatter.parse(timeStamp);
date.setMinutes(-2);
logger.info("Before converting : "+date);
DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd HH:mm:ss");
Here it is converting to my local time and subtracting 2 minutes from given time, but I don`t want to check the time zone here instead, what ever time I give it should just subtract 2 minutes.
Start with understanding into how Date works. When you do...
logger.info("Before converting : "+date);
The Date class uses it's toString method to format the the date/time information represented by the Date class into a human readable format. It doesn't "convert" the date/time value in anyway
So taking your code from above (and reworking it so it works), it outputs...
Before converting : Sat Jun 23 04:58:15 AEST 2018
20180623 04:58:15
on my machine - why are the values the same? Because the input doesn't have any time zone information, so the time is likely been treated as been in the machines local timezone (and the value is simply been formatted for output).
Date is just a container for the number of milliseconds since the Unix Epoch, it's format agnostic - meaning it carries not formatting information.
Date is also effectively deprecated - not to mention that setDate is also very much deprecated
A better (starting point) overall is to make use the newer date/time API introduced in Java 8 (and which has back port support for earlier versions of the API)
String timeStamp = "20180623 05:58:15";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss", Locale.ENGLISH);
LocalDateTime ldt = LocalDateTime.parse(timeStamp, formatter);
ldt = ldt.minusMinutes(2);
System.out.println(ldt);
System.out.println(ldt.format(formatter));
This will output...
2018-06-23T05:56:15
20180623 05:56:15
The input and the output are still consider as been in the machines local time zone.
but I don`t want to check the time zone here instead, what ever time I give it should just subtract 2 minutes
Just remember, the API still needs to have some concept of time zone, weather it's the local time zone or UTC/GMT, but since your input doesn't provide any kind of information, you need to make a choice over "how" best to handle that issue. The example above just "assumes" local time, but you could use ZonedDateTime and convert it to "common" time zone from which your operations are executed or, better yet, make all your strings carry time zone information
Oh, and for the love of my sanity, stop managing date/time values in String format - get them into an appropriate container as soon as possible and manage them from there - I've spent a week wrangling inappropriately formatted date strings and I'm not happy Jan, not happy
I receive the date from API in this format:
yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'
and convert it within this way:
String rawDate = "2017-05-11T15:46:48.2226756Z";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'", Locale.getDefault());
Date date = simpleDateFormat.parse(rawDate);
System.out.println(date); //Thu May 11 16:23:54 PDT 2017
However the date output is like that:
Thu May 11 16:23:54 PDT 2017
Output supposed to be:
Thu May 11 15:46:48 PDT 2017
How to convert the raw date properly?
SimpleDateFormat cannot handle any other number of decimals on the seconds than three (milliseconds), so there is no way to have it parse your string correctly. Furhermore the newer Java date and time classes are generally much more programmer-friendly and convenient. And they come with nanosecond precision (9 decimals on the seconds). So I am suggesting that you consider moving on to them.
As already commented Z means Zulu time zone, also known as UTC. So 2017-05-11T15:46:48.2226756Z means 15:46:48 UTC, equal to 8:46:48 Pacific Daylight Time. Your format is the ISO 8601 format for an instant, which the Instant class understand as its default, so parsing is easy:
Instant instant = Instant.parse(rawDate);
The result is
2017-05-11T15:46:48.222675600Z
Only thing to note about this is the two added zeroes. The toString method prints decimals in groups of three, enough groups to render the full precision. So with 7 decimals it prints 9.
To get the date in the Pacific time zone:
ZonedDateTime dateTime = instant.atZone(ZoneId.of("America/Los_Angeles"));
The result is what I predicted:
2017-05-11T08:46:48.222675600-07:00[America/Los_Angeles]
Now assume you got your raw date-time string from someone who misunderstood and really meant Thu May 11 15:46:48 PDT 2017 (it wouldn’t be the first time in history). Then you need to convert it to that. Again, while this would be cumbersome with the oldfashioned classes, it goes smoothly with the newer ones:
ZonedDateTime dateTime = instant.atOffset(ZoneOffset.UTC)
.atZoneSimilarLocal(ZoneId.of("America/Los_Angeles"));
The result is the one you asked for (except I am giving you all the decimals too):
2017-05-11T15:46:48.222675600-07:00[America/Los_Angeles]
For Android you get the newer date and time classes from the ThreeTenABP library.
Links
Oracle Tutorial: Trail: Date Time
The date and time classes for Android: ThreeTenABP
Question How to use ThreeTenABP in Android Project
The problem is that 'S' stands for milliseconds. So, in your case, you are telling it that the time is 15 hours, 46 minutes, 48 seconds and 2226756 milliseconds. If you add 2226756 milliseconds, i.e. 2226 seconds and 756 milliseconds to 15:46:48, you indeed get 16:23:54.
The easiest solution is probably to just find the period in your string, and truncate the string three places, later, i.e. convert it to:
2017-05-11T15:46:48.222
You can achieve this with the following line:
rawDate = rawDate.substring(0, rawDate.indexOf('.') + 4);
And then parse it with
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.getDefault());
Note that this does not correctly round the microseconds. In your case, for example, 222.6756ms should be rounded up to 223ms, not down to 222ms. If this matters, you can do this manually by examining the first dropped digit to see if it's 5 or above and adding a millisecond to date.
Update (re: Basil Bourque):
If you would like to actually respect the time-zone identifier in your time-string (which indicates UTC as explained below by Ole V.V.), you can simply add 'UTC' to the end of the string and parse it with that timezone in older versions of Java without using any additional libraries:
rawDate = rawDate.substring(0, rawDate.indexOf('.') + 4) + "UTC";
SimpleDateFormat sDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSz",
Locale.getDefault());
Date date = sDF.parse(rawDate);
You can just use below to parse.
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.getDefault());
In my app, I am using SimpleDateFormat to convert the Date object to a string. But sometime when I change the time zone one by one to test whether the date I enter is the same as the date converted to a string, I found that it shows a different date. For example, suppose I have Thu Mar 15 00:00:00 GMT+08:00 2012 in my Date object, Now when I convert it to a string using SimpleDateFormat it works fine, but when I change the time zone one by one and check whether the date converted to string is same as it stored in Date object then in some cases it shows as 14-Mar-2012 instead of showing 15-Mar-2012. Why this happen? Can anyone please suggest me how to solve this out?
Code I have used:
SimpleDateFormat m_sdFormatter = new SimpleDateFormat("dd-MMM-yyyy");
String selected_date = m_sdFormatter.format(btnSelectedDt.getTime());
try this ,hope it may help you..
private String getDate(long timeStamp) {
DateFormat objFormatter = new SimpleDateFormat("dd-MM-yyyy");
objFormatter.setTimeZone(TimeZone.getDefault());
Calendar objCalendar = Calendar.getInstance(TimeZone.getDefault());
objCalendar.setTimeInMillis(timeStamp * 1000);
String result = objFormatter.format(objCalendar.getTime());
objCalendar.clear();
return result;
}
For example suppose i have Thu Mar 15 00:00:00 GMT+08:00 2012 in my Date object,
You haven't got that (even though that's no doubt what toString displays). A Date object doesn't contain a time zone. It contains an instant in time, which can be interpreted as different dates and times based on the calendar and time zone you use to interpret it. So that's midnight in once specific time zone - but the Date object itself is just a number of milliseconds since the unix epoch.
It's not clear exactly what you're doing, but you shouldn't be surprised that changing the time zone used in SimpleDateFormat will change the date written out. If you can describe in more detail what the larger goal is, we may be able to help you more. Note that if you can use Joda Time instead, that's a much better date/time API - but I know that it's quite large for use in an Android app.
In your SimpleDateFormat, mention the locale,
DateFormat objFormatter = new SimpleDateFormat("dd-MM-yyyy", locale);
where locale is of your choice. For eg, I use Locale.ENGLISH as it contains the date format that I require. Otherwise when you change ure locale in the device, the simpledateformat changes to current locale and you end up getting the wrong date.