for example if the user input is 1.71 (1 hour and 71 minutes), then i want to convert it to 2.11 (2 hours and 11 minutes)
DecimalFormat time = new DecimalFormat("##.## p.m");
int userInput = 1.71;
System.out.print(time.format(userInput));
Parse the input as date and than format the date to your output format:
Scanner sc = new Scanner(System.in);
DateFormat df = new SimpleDateFormat("HH.mm");
DateFormat dfout = new SimpleDateFormat("H.mm a");
Date date = df.parse(sc.next());
System.out.println(dfout.format(date));
I'm not sure whether I get your question right, but shouldn't the following work?
int hours = (int)userInput;
decimal minutestmp = ((userInput - hours) * 60);
int minutes = (int)minutestmp;
String TimeString = hours + ":" + minutes;
Date date = new SimpleDateFormat("HH:mm").parse(TimeString);
String newTimeString = new SimpleDateFormat("H:mm").format(date);
ISO 8601
The ISO 8601 standard for date-time strings defines a format for what they call Durations: PnYnMnDTnHnMnS.
Joda-Time
The Joda-Time library knows how to parse and generate such strings.
So first, transform your input into such a string. Then feed that new string into Joda-Time. Lastly ask Joda-Time to recalculate the hours and minutes. All of this has been covered on StackOverflow multiple times. Please search for details.
To translate that input, replace the period, and prepend and append.
String d = "PT" + "1.71".replace( ".", "H") + "M"; // PT1H71M
Feed to Joda-Time.
Period period = Period.parse( d );
Normalize the minutes.
Period p = period.normalizedStandard();
Alternatively, you could tear apart the hours and minutes portions of your input, then feed them as ints to a constructor of Period.
Related
This question already has answers here:
Problem with parse a LocalDateTime using java 8
(2 answers)
How to parse a 1 or 2 digit hour string with Java?
(5 answers)
Error: Text '1/31/2020' could not be parsed at index 0 while trying to parse string date
(2 answers)
Closed 5 months ago.
I am using Java DateTimeFormatter for formatting given time and get difference between given start and end time. But I am getting below exception:
Exception in thread "main" java.time.format.DateTimeParseException: Text '1:23am' could not be parsed at index 0
Below is my code:
String dtStr = "1:23am-1:08am";
String t1 = dtStr.split("-")[0];
String t2 = dtStr.split("-")[1];
DateTimeFormatter format = DateTimeFormatter.ofPattern("hh:mma");
LocalTime time1 = LocalTime.parse(t1, format);
LocalTime time2 = LocalTime.parse(t2, format);
Duration dur = Duration.between(time1, time2);
System.out.println(dur.toMinutes() + " minutes " + dur.toSecondsPart() + " seconds");
I am not sure if I am doing anything wrong. Any help would be appreciated.
You cannot parse the Strings due to two h in your format pattern instead of just one, and due to am-pm of day being in lower case letters. The a in the pattern String expects (standard/default) upper case, like AM.
You can either manipulate the Strings as shown in the other answer(s), but you can also use a DateTimeFormatter that can handle lower-case things. All you need is to build one with a DateTimeFormatterBuilder and make it parseCaseInsensitive() and apply a Locale:
public static void main(String[] args) {
String dtStr = "1:23am-1:08am";
String t1 = dtStr.split("-")[0];
String t2 = dtStr.split("-")[1];
// build a formatter that parses lower case am-pm of day
DateTimeFormatter format = new DateTimeFormatterBuilder()
.parseCaseInsensitive() // handles lower- and upper-case
.appendPattern("h:mma")
.toFormatter(Locale.ENGLISH); // doesn't reliably work without a Locale
LocalTime time1 = LocalTime.parse(t1, format);
LocalTime time2 = LocalTime.parse(t2, format);
Duration dur = Duration.between(time1, time2);
System.out.println(dur.toMinutes() + " minutes " + dur.toSecondsPart() + " seconds");
}
Output:
-15 minutes 0 seconds
This is a little more flexible than manipulating the input before parsing, because this one can also parse upper-case am-pm of day.
You need to use the following pattern h:mma because of one-digit hour, also a parses AM/PM in uppercase
String dtStr = "1:23am-1:08am";
String t1 = dtStr.split("-")[0].toUpperCase();
String t2 = dtStr.split("-")[1].toUpperCase();
DateTimeFormatter format = DateTimeFormatter.ofPattern("h:mma");
LocalTime time1 = LocalTime.parse(t1, format);
LocalTime time2 = LocalTime.parse(t2, format);
Duration dur = Duration.between(time1, time2);
System.out.println(dur.toMinutes() + " minutes " + dur.toSecondsPart() + " seconds");
-15 minutes 0 seconds
java.time format specifications
When you put hh you are saying that hours have to be 2 digits you need just 1 and same should apply for the minutes h:ma
DateTimeFormatter docs
If the count of letters is one, then the value is output using the minimum number of digits and without padding. Otherwise, the count of digits is used as the width of the output field, with the value zero-padded as necessary
Next the "am" "pm" needs to be upper case to be parsed without an error.
String t1 = dtStr.split("-")[0].toUpperCase();;
String t2 = dtStr.split("-")[1].toUpperCase();;
DateTimeFormatter format = DateTimeFormatter.ofPattern("h:ma");
Note that if you don't have fixed length for minutes as 2 and pass for example 1:5am instead of 1:05am parsing would fail if you put h:mma as pattern
I'm parsing a timestamp which is "2022-01-12T17:17:34.512492+0000", this format is "yyyy-MM-dd'T'HH:mm:ss.SSSSSS'ZZZZ" (ISO8601).
I want to convert it in epoch unix time, I'm using java.text.SimpleDateFormat.
I tried two methods but both don't work:
1- First Method
val parsed = "2022-01-12T17:17:34.512492+0000"
val df: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'ZZZZ'")
val date = df.parse(parsed.toString)
val epoch = date.getTime
Error showed:
java.text.ParseException: Unparseable date: "2022-01-12T17:17:34.512492+0000"
2- This second Method shows an output but is incorrect
val parsed = "2022-01-12T17:17:34.512492+0000"
val df: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS'+0000'")
val date = df.parse(parsed.toString)
val epoch = date.getTime
println(epoch)
Output:
1642004766492
If you convert this epoch to HUMAN DATE: "Wednesday, 12 January 2022 16:26:06.492"
The hours,minutes and seconds are wrong.
SimpleDateFormat is outdated, as Gael pointed out.
The Time API now supports up to nanoseconds, so microseconds are not an issue here. You should use DateTimeFormatter with ZonedDateTime. Your pattern is slightly wrong. Checking the docs for Offset Z:
Offset Z: This formats the offset based on the number of pattern
letters. One, two or three letters outputs the hour and minute,
without a colon, such as '+0130'. The output will be '+0000' when the
offset is zero. Four letters outputs the full form of localized
offset, equivalent to four letters of Offset-O. The output will be the
corresponding localized offset text if the offset is zero. Five
letters outputs the hour, minute, with optional second if non-zero,
with colon. It outputs 'Z' if the offset is zero. Six or more letters
throws IllegalArgumentException.
You can also print the time using toInstant to make sure it was parsed correctly:
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
val parsed = "2022-01-12T17:17:34.512492+0000"
val p = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZZ"
val dtf = DateTimeFormatter.ofPattern(p)
val zdt = ZonedDateTime.parse(parsed, dtf)
println(zdt.toInstant) // 2022-01-12T17:17:34.512492Z
println(zdt.toInstant.toEpochMilli) // 1642004254512
Here is a nice article that explains in detail converting an ISO 8601 in Java. The comments at the end are particularly useful, as it shows the difference between the different patterns used.
looks like epoch has data in internal datetime format.
and you should convert it to string format
like this in java
public static String dateToString(Date d, String string_format) {
String result = "";
if(d != null) {
result = new SimpleDateFormat(string_format).format(d);
}
return result;
}
The timestamp you have has microseconds precision. Such precision is not supported by SimpleDateFormat. Also, Unix epoch time is usually up to milliseconds precision.
Possible solution here is to explicitly round the microseconds to milliseconds in the string before parsing, then use the yyyy-MM-dd'T'HH:mm:ss.SSSZ format.
String parsed = "2022-01-12T17:17:34.512492+0000";
String upToSeconds = parsed.substring(0, "yyyy-MM-ddTHH:mm:ss".length());
String microseconds = parsed.substring("yyyy-MM-ddTHH:mm:ss.".length(), "yyyy-MM-ddTHH:mm:ss.".length() + "SSSSSS".length());
String timezone = parsed.substring("yyyy-MM-ddTHH:mm:ss.SSSSSS".length());
String roundedMilliseconds = new BigDecimal(microseconds).divide(new BigDecimal("1000"), 0, RoundingMode.HALF_UP).toString();
String reformatted = upToSeconds + "." + roundedMilliseconds + timezone;
System.out.println(reformatted); // 2022-01-12T17:17:34.512+0000
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
long epoch = sdf.parse(reformatted).getTime();
System.out.println(epoch); // 1642007854512
System.out.println(Instant.ofEpochMilli(epoch)); // 2022-01-12T17:17:34.512Z
I need to parse two Strings in HH:MM format in Java:
String time1="10:45";
String time2="02:30";
Stupid but simple:
String time1 = "10:45";
String time2 = "02:30";
String[] split1 = time1.split(":");
String[] split2 = time2.split(":");
int total = 60 * Integer.parseInt(split1[0]) +
Integer.parseInt(split1[1]) +
60 * Integer.parseInt(split2[0]) +
Integer.parseInt(split2[1]);
int hours = total / 60;
int minutes = total - hours * 60;
System.out.println(hours + ":" + minutes);
Do you want to get the difference? have a look at the SimpleDateFormat, perhaps you use that to create a Date and then calculate on that.
Use SimpleDateFormat to get teh dates
DateFormat formatter = new SimpleDateFormat("HH:mm");
Date date = (Date)formatter.parse("10:20");
Then you can add the dates together.
You may have to do some logic to cope with times where the dateas go over different days. I would recommend using JodaTime for any date manipulation.
Not sure if this is relevant as not sure what the actual question is....
I cant quite figure out what the format should be to parse this date. Its a millisecond value followed by timezone. thx.
// so far tried: "S Z"
// "SSSSSSSSSSS-ZZZZ",
// "SSSSSSSSSSS-Z",
// etc.
Format formatter = new SimpleDateFormat("SSSSSSSSSSSS Z", Locale.CANADA);
// source string looks like this /Date(928164000000-0400)/
String temp = jsonUserObj.getString("DateOfBirth").substring(6, 6+17);
System.err.println("got date="+temp);
Date date = (Date) formatter.parseObject(temp);
You can do it without parser.
String[] parts = new String[]{temp.substring(0, temp.indexOf('-')), temp.substring(temp.indexOf('-') + 1)};
long millis = Long.parseLong(parts[0]);
parts[1] = parts[1].replaceAll("^0*(\\-?[0-9]*)$", "$1");
int timeZone = Integer.parseInt(parts[1]);
int rawOffset = (timeZone / 100) * 3600000 + (timeZone % 100);
GregorianCalendar cal = new GregorianCalendar();
cal.setTimeInMillis(millis);
cal.setTimeZone(new SimpleTimeZone(rawOffset, "GMT"));
SimpleDateFormat expects a milliseconds value < 1000, as it expects you would increment seconds, then minutes, etc, for larger values.
You'll need to convert the value first; this post might help: Unix epoch time to Java Date object
In my Java application I use a DateFormat instance to parse date inputs.
DateFormat fmt;
fmt = DateFormat.getDateInstance(DateFormat.DEFAULT) // dd.MM.yyyy for de_DE
The problem is that the user insists to enter dates in the form 31.12.11.
Unfortunately this is parsed to 31.12.11. (0011-12-31 in ISO format) Instead I want the parsed date to become 31.12.2011 (2011-12-31 in ISO format).
Can I modify the date format to somehow parse inputs that way?
You will have to parse with a format of dd.MM.yy and re-format with a format of yyyy-MM-dd
DateFormat sdfp = new SimpleDateFormat("dd.mm.yy");
Date d = sdfp.parse(input);
DateFormat sdff = new SimpleDateFormat("yyyy-MM-dd");
String date = sdff.format(d);
See the Java API for more info on setting patterns.
http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
Your solution here is sufficiently simple as to allow for the use of SimpleDateFormat, which includes the method set2DigitYearStart(Date startDate). Perhaps it looks something like this.
String userInput = "31.12.11";
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yy");
format.set2DigitYearStart(new GregorianCalendar(2001,1,1).getTime());
Date userEnteredDate = format.parse(userInput, 1); // parsed to 2011-12-31
Yes, you could parse using DateFormat.SHORT instead of DEFAULT.
Or possibly, try to parse with SHORT, and then try other formats if that doesn't work.
You can parse this date using SimpleDateFormat but how you will determine that was 1911 or 2011 or anything else. you should use year format as yyyy.
If you use GWT, you don't have access to SimpleDateFormat, so here is some code to do it manually:
String[] parts = dateText.split(" ");
// Convert 2 digit date to 4 digits
if (parts.length == 3 && parts[2].length() == 2) {
int year = Integer.valueOf(parts[2]);
// Allow 5 years in the future for a 2 digit date
if (year + 100 > new Date().getYear()+5) {
year = year + 1900;
}
else {
year = year + 2000;
}
dateText = parts[0] + " " + parts[1] + " " + String.valueOf(year);
}
This assumes you have validated that the dateText is separated with spaces.
An approximation:
int twoDigitYear = 11;
int fourDigitYear = 0;
DateTime now = new DateTime();
if (twoDgYear + 2000 > now().getYear()) {
fourDigitYear = twoDigitYear + 1900;
}else{
fourDigitYear = twoDigitYear + 2000;
}
May or may not fit your need...