Java String to date conversion error for format yyyyMMddhhmmss - java

I am getting error only for the specific string field ,I have given my code below
public static void main(String[] args) throws ParseException {
String sDate1="201710164425";
Date date1=new SimpleDateFormat("yyyyMMddhhmmss").parse(sDate1);
System.out.println(sDate1+"\t"+date1);
}
If i change String to addding 0 before 4 sDate1="2017101604425"; it works fine, I get Mon Oct 16 04:42:05 IST 2017, but my input comes in this way sDate1="201710164425";
Help me to have a better solution for this ,Thanks in advance

yyyyMMddhhmmss <- format
201710164425 <- data
so for 4th hour you need to do 04 (hh) instead of 4. Same for minutes.

What you want is to have an "hour value" without leading zero, I also see that minutes and/or seconds should be the same, so you could use a time format like Hms.
H : Hour in day (0-23) or (k : Hour in day (1-24) )
m : Minute in hour
s : Second in minute
Compared to HHmmss, having a format like Hms would only take the least amount of digit for each field (that more complicated but it's the idea).
Problem
That could be miss interpreted. Let say I want to send you a time like 01:21:05, it will look like 1215 to match the pattern you need.
new SimpleDateFormat("Hms")
1215 -> 01:02:15
See the problem ? 01:21:05 will be come 01:02:15.
I always suggest to use leading zero (two digit) for every field to prevent any mistake.
Solution
Use leading zero
Use two digit for each of your field to prevent any problem
new SimpleDateFormat("HHmmss")
012105 -> 01:21:05
Add some separators
You can define a pattern to use separator between each field:
new SimpleDateFormat("H:m:s")
1:21:5 -> 01:21:05

You can achieve what you want using another pattern in SimpleDateFormat:
yyyyMMddKmmssa
Where
K - Hour in am/pm (0-11)
a - Am/pm marker
Notice that you need the last 'a'. If you want just a single 4 to indicate both 04:00 and 16:00, you need something to differentiate between them.

Related

How can I make a leading zero in DateTime-Pattern optional

I have a user input field and would like to parse his date, whatever he puts in.
The user might provide his date with a leading zero or without one, so I wanna be able to parse an input like this
02.05.2019
and also this
2.5.2019
But as far as I can tell there is no way to make the leading zero optional, either always have 2 digits like 01, 03, 12 and so on, or only have the necessary digits like 1, 3, 12.
So apparently I have to decide whether to allow leading zeros or not, but is there seriously no way to make the leading zero optional ?
Well, I tested a pattern that included a leading zero dd.MM.uuuu and I tested a pattern that did not include a leading zero d.M.uuuu and when I parsed the wrong input with the wrong pattern exceptions were thrown.
Therefore my question is if there is a way to make the leading zero optional.
This is trivial when you know it. One pattern letter, for example d or M, will accept either one or two digits (or for year up to 9 digits).
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("d.M.u");
System.out.println(LocalDate.parse("02.05.2019", dateFormatter));
System.out.println(LocalDate.parse("3.5.2019", dateFormatter));
System.out.println(LocalDate.parse("4.05.2019", dateFormatter));
System.out.println(LocalDate.parse("06.5.2019", dateFormatter));
System.out.println(LocalDate.parse("15.12.2019", dateFormatter));
Output:
2019-05-02
2019-05-03
2019-05-04
2019-05-06
2019-12-15
I searched for this information in the documentation and didn’t find it readily. I don’t think it is well documented.
You can create a DateTimeFormatter with a custom format like this
DateTimeFormatter.ofPattern("d.M.yyyy")
Then you can parse dates if they provide 1 or 2 digits for the day and month.
String input = "02.5.2019";
LocalDate date = LocalDate.parse(input, DateTimeFormatter.ofPattern("d.M.yyyy"));
I've used LocalDate here from the new java.time package so I'm assuming that your java version is recent.
Your suggested date format should work - just as this test:
#Test
public void test() throws ParseException {
SimpleDateFormat f = new SimpleDateFormat("d.M.yyyy");
f.parse("7.8.2019");
f.parse("07.08.2019");
f.parse("007.008.002019");
}
The DateTimeFormatter will not accept leading zeros for year in comparison, but leading zeros for day and month are not an issue:
#Test
public void test2() throws ParseException {
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
DateTimeFormatter f = builder.appendPattern("d.M.yyyy").toFormatter();
f.parse("7.8.2019");
f.parse("07.08.2019");
f.parse("007.008.2019");
}

determing the string containg the date is of US format or of UK format

I have one question is that lets say I have a string which is as shown below
String d = "03/03/2015"
now i wanted to know that string that stores tyhe date is of UK format date or US format date , so for that i want to build a logic which will scan the value from the second forward slash , lets say in this from the second slash the value is 03 so it will scan the value from the second forward slash and if this value is less or equal to 12 then this is month else this is date as date can be 30 or 31 .
please advise is there any hack or way i can implement to detect whether the string store the date is of US format MM/dd/yyyy or it is UK format that is dd/MM/yyyy
There is no way to do that, except if you have a bunch of dates of the EXACT same type, and you are ABSOLUTELY sure that at least one of them contains a day higher than 12 .
The answer is no, you can't determine if that String is a US or UK date. You would be able to see if it is if the first 03 or second 03 was above 12 and one wasn't as there are only 12 months in the year (duh!).
EDIT - Date doesn't have a locale, was getting mixed up with a DateFormat.

What format is this date? [17/6/2015 5:50:22 5 -120]

Context: Getting date from a third party data source as below. I am using Pig script to transform this string to date.
Script:
a= LOAD '/user/hit_data.tsv' using PigStorage('\t');
b= FOREACH a GENERATE $0 as post_t_time_info;
c= FOREACH b GENERATE ToDate(post_t_time_info,'DD/MM/YYYY HH:mm:ss e ZZZ')
Sample value the date object takes:
17/6/2015 5:50:22 5 -120
17/6/2015 0:7:6 5 240
I am unable to understand what is -120/240. I tried with timezone(ZZZ) and milliseconds (SSS) but appears to be incorrect.
My current format used is 'DD/MM/YYYY HH:mm:ss e X', where X is unknown and looking forward for appropriate pattern for it.
Thanks!
Reference:
http://userguide.icu-project.org/formatparse/datetime
http://www.unicode.org/reports/tr35/tr35-25.html#Time_Zone_Fallback
Chances are that -120 and 240 are indeed time zone offsets. They are likely in terms of minutes, not hours. However, there's no standard for that, so it could be minutes east of GMT, or minutes west of GMT.
In other words, -120 could be UTC+02:00, or UTC-02:00. 240 could be UTC+04:00, or UTC-04:00.
For example, if it was obtained from the JavaScript Date object's getTimezoneOffset function, the sign will be opposite of what you might expect. It would have positive values to the west, while the usual ISO8601 convention has positive values to the east.
Since you are the one obtaining the data, you are in a much better position than us to identify the source and disambiguate. If it's from a third-party, look in their specs, or contact them and ask.
Also - You said you were using Apache Pig, but according to their documentation, the ToDate function uses Java's SimpleDateFormat - which does not use the same format qualifiers as ICU, nor does it have a format qualifier that recognizes time zone offsets in terms of minutes. You will likely need to write your own function instead of using just the built-in ToDate.

How to parse military time (including truncated partials) into a Time?

Official airline departure and arrival times are often provided in hour and minutes. The following are typical examples:
1830 - 6:30 pm
730 - 7:30 am
30 - 30 minutes after midnight (ie 12:30 am)
The first two can be parsed using DateTimeFormatter with HHmm and Hmm. The third results in a parsing error, and attempting to parse it with only minutes (mm) results in a different error: Unable to obtain LocalTime from TemporalAccessor: {MinuteOfHour=30}
Constraints:
I would like to provide a general solution to handle this using formatters if possible, as i don't want to break parsing for all other time variants that work.
Obviously I could pre-process the incoming data to prepend missing zeros, but i have many GB of data and would like to avoid an additional pass.
Thanks for your help.
Update: An obvious solution is to prepend zeros in the same pass. For example, using Guava:
stringValue = Strings.padStart(stringValue, 4, '0');
LocalTime.parse(stringValue, TypeUtils.timeFormatter);
Still curious if there a way to do this only with standard formatting codes like hh and mm.
Well, you can create a default using DateTimeFormatterBuilder:
String timeStr = "30";
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ofPattern("mm"))
.parseDefaulting(ChronoField.HOUR_OF_DAY,0)
.toFormatter();
LocalTime parsedTime = LocalTime.parse(timeStr, formatter);

Convertion of DateTimeFormat in java!

I just need a small help regarding the DateTime format in java.I am writing a simple chat application based on yahoo messanger,in which I will read the packet of yahoo messanger and display the chat messages.Now I want to display the time from the given header.In a particular article it is said the "timestamp" will be 0x477BBA61(decimal 1199290977) which means "Wed, 2 Jan 2008 16:22:57 GMT" .
I am trying to reveal how that decimal is converted to that particular date.I tried to write a simple java application to convert that and its giving some other time.
public static void main(String[] arg)
{
Calendar obj = Calendar.getInstance();
obj.setTimeZone(TimeZone.getTimeZone("GMT"));
obj.setTimeInMillis(1199290977l);
System.out.println( obj.get(Calendar.HOUR)+":"+obj.get(Calendar.MINUTE));
}
output:9:8
Can anybody help me with this?
Your value of 1199290977L is wrong. That's measuring in seconds since the Unix epoch (midnight on January 1st 1970 UTC) - you need to multiply it by 1000 to get milliseconds since the epoch.
You're also using Calendar.HOUR which is the 12-hour clock instead of Calendar.HOUR_OF_DAY which is the 24-hour clock. This code:
Calendar obj = Calendar.getInstance();
obj.setTimeZone(TimeZone.getTimeZone("GMT"));
obj.setTimeInMillis(1199290977000L);
System.out.println(obj.get(Calendar.HOUR_OF_DAY) + ":" +
obj.get(Calendar.MINUTE));
... prints 16:22.
However, you should definitely use the java.text.DateTimeFormat class instead of doing this yourself - or, ideally, use Joda Time instead.
Imho to proceed you need to know:
whether or not that number is milliseconds or not
what is the starting point (in java is January 1, 1970, 00:00:00 GMT)
The timezone is probably in seconds; try to multiply the value by 1000 to get the milliseconds which Calendar expects.
You need to use a SimpleDateFormat - look at the documentation, it is pretty easy to understand, plus it includes a lot of examples (so you don't need to search for "date format tutorial" or something like that :))
EDIT: Ooops, I missed the part where you are passing the time in seconds instead of milliseconds and the result time is wrong, I misinterpreted your question and thought that you want to just parse the time, Jon's answer is better :)

Categories