I have three dates as String objects in the format: dd:HH:mm:ss
00:1:9:14
00:3:10:4
00:3:39:49
How do I add these dates in Java to get the sum (00:7:59:07)?
Sample code:
SimpleDateFormat sdf = new SimpleDateFormat("dd:HH:mm:ss");
Date d1 = sdf.parse("00:1:9:14");
Date d2 = sdf.parse("00:3:10:4");
Date d3 = sdf.parse("00:3:39:49");
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
Date d = new Date(d1.getTime() + d2.getTime() + d3.getTime());
System.out.println(d);
Output(wrong):
Wed Dec 31 01:09:14 IST 1969
Wed Dec 31 03:10:04 IST 1969
Wed Dec 31 03:39:49 IST 1969
Sun Dec 28 20:59:07 IST 1969
The dd format includes the day of the month. So your value of 00 will underflow if you use SimpleDateFormat (or Java Date because it also includes a day of the month). Instead, parse your time parts and do the math yourself.
For example, you could create a class TimePart with days, hours, minutes and seconds like
static class TimePart {
int days = 0;
int hours = 0;
int minutes = 0;
int seconds = 0;
static TimePart parse(String in) {
if (in != null) {
String[] arr = in.split(":");
TimePart tp = new TimePart();
tp.days = ((arr.length >= 1) ? Integer.parseInt(arr[0]) : 0);
tp.hours = ((arr.length >= 2) ? Integer.parseInt(arr[1]) : 0);
tp.minutes = ((arr.length >= 3) ? Integer.parseInt(arr[2]) : 0);
tp.seconds = ((arr.length >= 4) ? Integer.parseInt(arr[3]) : 0);
return tp;
}
return null;
}
public TimePart add(TimePart a) {
this.seconds += a.seconds;
int of = 0;
while (this.seconds >= 60) {
of++;
this.seconds -= 60;
}
this.minutes += a.minutes + of;
of = 0;
while (this.minutes >= 60) {
of++;
this.minutes -= 60;
}
this.hours += a.hours + of;
of = 0;
while (this.hours >= 24) {
of++;
this.hours -= 24;
}
this.days += a.days + of;
return this;
}
#Override
public String toString() {
return String.format("%02d:%02d:%02d:%02d", days, hours, minutes,
seconds);
}
}
Then your test-cases like
public static void main(String[] args) {
try {
TimePart d1 = TimePart.parse("00:1:9:14");
TimePart d2 = TimePart.parse("00:3:10:4");
TimePart d3 = TimePart.parse("00:3:39:49");
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
TimePart d4 = d1.add(d2).add(d3);
System.out.println(d4);
} catch (Exception e) {
e.printStackTrace();
}
}
And it seems to perform the addition correctly like
00:01:09:14
00:03:10:04
00:03:39:49
00:07:59:07
The above sum is arithmetic addition so you need a ref --here d0 (default epoch). Date class has a lot of problems beware...
SimpleDateFormat sdf = new SimpleDateFormat("dd:HH:mm:ss");
Date d0 = sdf.parse("00:00:00:00"); // ref
Date d1 = sdf.parse("00:01:09:14");
Date d2 = sdf.parse("00:03:10:04");
Date d3 = sdf.parse("00:03:39:49");
System.out.println(d0);
System.out.println(d1);
System.out.println(d2);
System.out.println(d3);
Date d = new Date(d1.getTime() + d2.getTime() + d3.getTime() - 2 * d0.getTime()); // impt
System.out.println(d);
Note:- Date addition is not an easy task, think twice.
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
String s1 = "01:02:03";
String s2 = "10:12:13";
Date d1 = format.parse(s1);
Date d2 = format.parse(s2);
int sec = d1.getSeconds() + d2.getSeconds();
int min = d1.getMinutes() + d2.getMinutes();
int hr = d1.getHours() + d2.getHours();
Time sum = new Time(hr, min, sec);
System.out.println(sum); // Output: 11:14:16
Do your strings represent/denote amounts of time? So use the Duration class. Let’s first write an auxiliary method that parses a string into a Duration:
private static Duration parseDuration(String timeString) {
// First convert the string to ISO 8601 through a regex
String isoTimeString = timeString.replaceFirst("^(\\d+):(\\d+):(\\d+):(\\d+)$", "P$1DT$2H$3M$4S");
// Then parse into Duration
return Duration.parse(isoTimeString);
}
Duration.parse() requires ISO 8601 format, it goes like PT1H9M14S for a period of time of 1 hour 9 minutes 14 seconds. Or optionally P0DT1H9M14S. The 0D for 0 days goes before the T. So I use a regular expression (AKA a regex) to modify your string format into ISO 8601 before parsing it. The $1, $2, etc., in the replacement string refer to what was matched inside the round brackets, the so-called groups in the regular expression.
Now we can add the times up:
String[] timeStrings = { "00:1:9:14", "00:3:10:4", "00:3:39:49" };
Duration totalTime = Duration.ZERO;
for (String timeString : timeStrings) {
Duration dur = parseDuration(timeString);
totalTime = totalTime.plus(dur);
}
System.out.println(totalTime);
Output:
PT7H59M7S
7 hours 59 minutes 7 seconds. If you want, you may format it back into your format of 00:7:59:07. Search for how.
What went wrong in your code?
Your first mistake seems to have been before writing the code: thinking of the times as dates. They are not, and it would not make any sense to add dates. What is the sum of April 7 and December 25?
Mislead by this thinking, you tried to parse into Date objects. A Date is a point in time, not an amount of time, so this is wrong. Other than that the Date class is poorly designed, and the SimpleDateFormat class that you also tried to use is notoriously troublesome. Fortunately we’ve got no use for them here, and also for dates and times they are long outdated, superseded by java.time, the modern Java date and time API, of which Duration is but one of many classes.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
Documentation of…
String.replaceFirst() on the use of a regular expression
Duration
Question: How to format a duration in java? (e.g format H:MM:SS); some of the answers are using the Duration class.
private static String addTimes(String time1, String time2) throws ParseException {
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(dateFormat.parse(time1));
c2.setTime(dateFormat.parse(time2));
c1.add(Calendar.HOUR, c2.get(Calendar.HOUR));
c1.add(Calendar.MINUTE, c2.get(Calendar.MINUTE));
c1.add(Calendar.SECOND, c2.get(Calendar.SECOND));
return dateFormat.format(c1.getTime());
}
addTimes("1:9:14", "3:10:4");
Output: 04:19:18
Related
I want to translate a date to human readable format. I am using DateUtils. getRelativeDateTimeString, but this does not fit the criteria. The output I am getting looks like: 1 hour, 15 min. ago, etc.
I want to know if it is possible to change the format to:
3m instead of 3 min. ago,
1h instead of 1 hour. 15 min. ago etc.
using DateUtils or is there another way to do this?
To be more precise I am looking for an Android equivalent of this angular-filter where you can easily change the format of the relative date (for example: {{minutes}} minutes ago to {{minutes}}m.
To make myself clear, I am not searching for a way to format a date, but to translate a date to human readable format such as 'today', '1 hr', '38 min' (simillar to facebook's relative dates).
After some research, I found out some libraries like Time4A, Joda-Time, PrettyTime, Android-Ago.
However, I have decided not to use a library and override its text resources, but to create a method and store text in strings.xml for possible future localization.
private static final int SECOND_MILLIS = 1000;
private static final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
private static final int HOUR_MILLIS = 60 * MINUTE_MILLIS;
private static final int DAY_MILLIS = 24 * HOUR_MILLIS;
private static final int WEEK_MILLIS = 7 * DAY_MILLIS;
public static String getTimeAgo(Date date, Context context) {
Date now = Calendar.getInstance().getTime();
final long diff = now.getTime() - date.getTime();
if (diff < SECOND_MILLIS) {
return context.getString(R.string.just_now);
} else if (diff < MINUTE_MILLIS) {
return diff / SECOND_MILLIS + context.getString(R.string.seconds_ago);
} else if (diff < 2 * MINUTE_MILLIS) {
return context.getString(R.string.a_minute_ago);
} else if (diff < 59 * MINUTE_MILLIS) {
return diff / MINUTE_MILLIS + context.getString(R.string.minutes_ago);
} else if (diff < 90 * MINUTE_MILLIS) {
return context.getString(R.string.an_hour_ago);
} else if (diff < 24 * HOUR_MILLIS) {
return diff / HOUR_MILLIS + context.getString(R.string.hours_ago);
} else if (diff < 48 * HOUR_MILLIS) {
return context.getString(R.string.yesterday);
} else if (diff < 6 * DAY_MILLIS) {
return diff / DAY_MILLIS + context.getString(R.string.days_ago);
} else if (diff < 11 * DAY_MILLIS) {
return context.getString(R.string.a_week_ago);
} else {
return diff / WEEK_MILLIS + context.getString(R.string.weeks_ago);
}
}
Use the built-in DateUtils utility library that was included in API level 3.
CharSequence getRelativeDateTimeString (Context c,
long time,
long minResolution,
long transitionResolution,
int flags) Return string describing the elapsed time since startTime formatted like "[relative time/date], [time]".
Example output strings for the US date format:
3 min. ago, 10:15 AM Yesterday, 12:20 PM Dec 12, 4:12 AM 11/14/2007,
8:20 AM
You should use SimpleDateFormat and specify your desired template. Which in your case would be something like this:
String template = "H'h', m'm'";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(template, Locale.getDefault());
String formatted = simpleDateFormat.format(new Date());
Why don't you parse the Date to the format you want?
With string.replace() you can do it in one line of code.
Edit 1: I usually use SimpleDateForma this way, hope it helps:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String currentDateandTime = sdf.format(new Date());
you will need this imports ( i think that Android automatically imports):
import java.text.SimpleDateFormat;
import java.util.Date;
Edit 2: In your example what you have to do is:
SimpleDateFormat sdf = new SimpleDateFormat("HH'h' mm'm'");
String currentDateandTime = sdf.format(new Date());
System.out.println("Today in dd-MM-yy:HH:mm:SS : " + date);
I have 2 string in java (HH:MM:SS) please take note this is not time, but duration, i used end time - start time to get these values:
Case1:
duration1 = "12:04:45";
duration2 = "13:04:45";
Expected result: duration1 - duration 2 = "-1:00:00" (Note that there is negative)
Case2:
duration1 = "15:13:32";
duration2 = "12:04:45";
Expected result: duration1 - duration 2 = "3:08:47"
How can i do that? My attempt for the Case1 (codes modified from Java add dates of format dd:HH:mm:ss):
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
String s1 = "12:04:45";
String s2 = "13:04:45";
Date d1 = format.parse(s1);
Date d2 = format.parse(s2);
int sec = d1.getSeconds() - d2.getSeconds();
int min = d1.getMinutes() - d2.getMinutes();
int hr = d1.getHours() - d2.getHours();
Time sum = new Time(hr, min, sec);
System.out.println(sum); // Output: 23:00:00 which is wrong
Using LocalTime or date calculations like some people suggest doesn't work if your period involved more than 24 hours since that doesn't fit in a day.
If you don't have Java 8, you can use JodaTime. I've just checked that this code also works with JodaTime 1.6.2, which is the last version that still works with JDK 1.4.2.
PeriodFormatter formatter = new PeriodFormatterBuilder()
.printZeroAlways().minimumPrintedDigits(2)
.appendHours().appendSuffix(":").appendMinutes().appendSuffix(":").appendSeconds()
.toFormatter();
Period period1 = formatter.parsePeriod("12:04:45");
Period period2 = formatter.parsePeriod("13:04:45");
Period difference1 = period1.minus(period2).normalizedStandard();
System.out.println(formatter.print(difference1));
Period period3 = formatter.parsePeriod("15:13:32");
Period period4 = formatter.parsePeriod("12:04:45");
Period difference2 = period3.minus(period4).normalizedStandard();
System.out.println(formatter.print(difference2));
Output:
-01:00:00
03:08:47
JodaTime:
Version 1.6.2 source: https://github.com/JodaOrg/joda-time/releases/tag/v1.6.2
Version 1.6.2 Maven Jar artifact: http://mvnrepository.com/artifact/joda-time/joda-time/1.6.2
With the Java time API you could use a Duration to calculate the duration and format it as you want:
String s1 = "12:04:45";
String s2 = "13:04:45";
LocalTime t1 = LocalTime.parse(s1);
LocalTime t2 = LocalTime.parse(s2);
Duration d = Duration.between(t2, t1);
System.out.println(d); //PT-1H
If you want to print it as -1:00:00 you will need to tweak the output format. It could look like this:
private static String toHHMMSS(Duration d) {
long hours = d.toHours();
int minutes = (int) (d.toMinutes() % 60);
int secs = (int) (d.getSeconds() % 60);
return hours + ":" + minutes + ":" + secs;
}
Use Calendar to calculate the time difference.
You can query each field and/or format as a time string as this example shows:
private Calendar getTimeDiffDate(Date d1, Date d2) {
Calendar c = Calendar.getInstance();
c.setTime(new Date(d1.getTime()-d2.getTime()));
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
// Format as a time string:
String formattedTime = formatter.format(c.getTime());
System.out.println("formattedTime: "+formattedTime);
// Query by each field:
System.out.println("Hours: "+c.get(Calendar.HOUR));
System.out.println("Minutes: "+c.get(Calendar.MINUTE));
System.out.println("Seconds: "+c.get(Calendar.SECOND));
return c;
}
For someone else who might stumble here, the link refered to in this question gives misleading results
My First Date: 1986-04-08. Current Date: 2013-11-28.
Code:
public long seconds(Date date){
String formattedDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",getResources().getConfiguration().locale).format(Calendar.getInstance().getTime());
String DateStr=String.valueOf(formattedDate);
Date d = null;
try {
d = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",getResources().getConfiguration().locale).parse(DateStr);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
java.sql.Date dx = new java.sql.Date(d.getTime());
Date d1 = date;
Date d2 = dx;
t4.setText("BirthDate"+date+"\n Current Date:"+dx);
long seconds = (d2.getTime()-d1.getTime())/1000;
return seconds;
}
However when I check the results here: http://www.calculator.net/age-calculator.html?today=04%2F04%2F1986&ageat=11%2F28%2F2013&x=32&y=10 it gives me a slight different result. I am unsure where I am going wrong.
The online service you link to is wrong: it counts the age as whole days and then assumes that each day is exactly 24 hours long. Most of the time that's correct, but in most places in the world there are days with daylight savings time transitions and timezone transitions, meaning there have been days with 23, 25, or some other number of hours. The number you get from your Java code is more precise.
I think you're somehow mixing java.sql.Date and java.util.Date.
I would try simplifying the code. Something like this.
public class Test012 {
public static void main(String[] args) throws Exception {
System.out.println( seconds() );
System.out.println( seconds2() );
System.out.println( days3() );
}
public static long seconds() throws Exception {
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date d1 = sdf.parse("1986-04-08");
java.util.Date d2 = sdf.parse("2013-11-28");
return ( d2.getTime() - d1.getTime() ) / 1000;
}
public static long seconds2() throws Exception {
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date d1 = sdf.parse("1986-04-08");
java.util.Date d2 = new java.util.Date();
return ( d2.getTime() - d1.getTime() ) / 1000;
}
public static long days3() throws Exception {
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date d1 = sdf.parse("2008-01-01");
java.util.Date d2 = sdf.parse("2009-01-01");
return ( d2.getTime() - d1.getTime() ) / 1000 / 60 / 60 / 24;
}
}
I also tried
select datediff(ss, '4/8/1986', '11/28/2013') --- US date format
in SQL Server and it prints the same thing as this java program,
it prints 872294400. So this seems to be the correct value.
Are you sure the dates coming on your input are the right ones
(are equal to those I hardcoded in my test program)?
I would check that too.
Also, are you sure your dates have zero time parts? That's what the link/service you posted assumes.
Try this code:--
public static long secondsBetween(Calendar startDate, Calendar endDate) {
Calendar date = (Calendar) startDate.clone();
long daysBetween = 0;
while (date.before(endDate)) {
date.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween*24*3600;
}
Hope it helps you.. Enjoy..!
I have the following method to sum time:
public static String sumTime(String date1, String date2) throws ParseException {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss.SSS");
Date d1 = formatter.parse(date1);
Date d2 = formatter.parse(date2);
calendar.setTime(d2);
d1 = DateUtils.addHours(d1, calendar.get(Calendar.HOUR_OF_DAY));
d1 = DateUtils.addMinutes(d1, calendar.get(Calendar.MINUTE));
d1 = DateUtils.addSeconds(d1, calendar.get(Calendar.SECOND));
d1 = DateUtils.addMilliseconds(d1, calendar.get(Calendar.MILLISECOND));
return formatter.format(d1);
}
DateUtils is from Apache Commons Lang 3
It works quite well for what I want, unless the sum is bigger than 24 hours.
For example:
String time = "00:00:00.000";
try {
for (int i = 0; i < 24; i++) {
time = sumTime(time, "01:00:00.123");
}
System.out.println(time);
} catch (ParseException e) {
e.printStackTrace();
}
The result is:
00:00:02.952
But this is what I'd like it to be:
24:00:02.952
Is there any (easy) way to accomplish that?
I don't mind using different libraries/methods, as long as I get the correct result.
Keep in mind that time will always start in 00:00:00.000;
Have you thought about using days to represent each set of 24 hours? You could add something in your sumTime method, and have it add days. SimpleDateFormater can use days, maybe this will help:
http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
java.util.Date is not so strong in this area. See the Joda Time for a library that handles this properly.
I don't have access to an installation just now. The code will be close to this:
DateTimeFormatter dtf = DateTimeFormat.forPattern("HH:mm:ss.SSS");
DateTime start = dtf.parseDateTime(date1);
DateTime end = dtf.parseDateTime(date2);
PeriodFormatter pf = new PeriodFormatterBuilder()
.printZeroAlways().appendHours().appendSeparator(":")
.appendMinutes().appendSeparator(":")
.appendSeconds().appendSeparator(":")
.appendMillis3Digit().toFormatter();
return pf.print(new Period(start, end, PeriodType.time()));
Date is not the right thing class to use. Date is a instant of time, not a "Date Difference".
The right thing to do will be to use a library like Joda Time as someone has already suggested. If you don't want to do so - here's a possible alternative:
Parse the string into hours, minutes and seconds yourself, and then add it yourself.
I would encourage you to look into a "well accepted" library though. There may be things I'm not thinking of in my solution. Also, you have add all the error checking.
Here's the starter code:
public class TimeInterval {
short milliSeconds;
short seconds;
short minutes;
int hours;
public TimeInterval (String dateString) {
// HHHHHH:MI:SS.SSS
Pattern pattern = Pattern.compile("(\\d+):(\\d\\d):(\\d\\d)\\.(\\d\\d\\d)");
Matcher matcher = pattern.matcher(dateString);
if ( matcher.find() ) {
hours = Integer.parseInt(dateString.substring(matcher.start(1), matcher.end(1)));
minutes = Short.parseShort(dateString.substring(matcher.start(2), matcher.end(2)));
seconds = Short.parseShort(dateString.substring(matcher.start(3), matcher.end(3)));
milliSeconds = Short.parseShort(dateString.substring(matcher.start(4), matcher.end(4)));
}
}
private TimeInterval() {
}
public TimeInterval add(TimeInterval interval) {
TimeInterval ret = new TimeInterval();
ret.milliSeconds = (short) ((interval.milliSeconds + milliSeconds)%1000);
int carry = (interval.milliSeconds + milliSeconds)/1000;
ret.seconds = (short) ((interval.seconds + seconds)%60 + carry );
carry =(interval.seconds + seconds)/60;
ret.minutes = (short) ((interval.minutes + minutes)%60 + carry);
carry = (interval.minutes + minutes)/60;
ret.hours = (interval.hours + hours + carry);
return ret;
}
#Override
public String toString() {
return String.format("%d:%02d:%02d.%03d", hours, minutes, seconds, milliSeconds);
}
}
Using this class your program will be like :
TimeInterval time = new TimeInterval("00:00:00.000");
try {
for (int i = 0; i < 24; i++) {
time = time.add(new TimeInterval("01:00:00.123"));
}
System.out.println(time.toString());
} catch (ParseException e) {
e.printStackTrace();
}
Have you tried Joda-Time which actually has direct support for this sort of thing?
PeriodFormatterBuilder builder = new PeriodFormatterBuilder();
builder.printZeroAlways()
.minimumPrintedDigits(2)
.appendHours()
.appendSeparator(":").appendMinutes()
.appendSeparator(":").appendSeconds()
.appendSeparator(".").appendMillis3Digit();
PeriodFormatter formatter = builder.toFormatter();
PeriodParser parser = builder.toParser();
String s1 = "11:00:00.111";
String s2 = "23:00:00.111";
MutablePeriod p1 = new MutablePeriod();
MutablePeriod p2 = new MutablePeriod();
parser.parseInto(p1, s1, 0, Locale.getDefault());
parser.parseInto(p2, s2, 0, Locale.getDefault());
p1.add(p2);
System.out.println(formatter.print(p1));
Prints
34:00:00.222
I have a string holding a start time and an end time in this format 8:30AM - 9:30PM I want to be able to strip out the AM - and the PM and convert all the times to 24 hour format so 9:30PM would really be 21:30 and also have both the times stored in 2 different variables, I know how to strip the string into substrings but Im not sure about the conversion, this is what I have so far. the time variable starts out holding 8:30AM - 9:30PM.
String time = strLine.substring(85, 110).trim();
//time is "8:30AM - 9:30PM"
String startTime;
startTime = time.substring(0, 7).trim();
//startTime is "8:30AM"
String endTime;
endTime = time.substring(9).trim();
//endTime "9:30AM"
Working code (considering that you managed to split the Strings):
public class App {
public static void main(String[] args) {
try {
System.out.println(convertTo24HoursFormat("12:00AM")); // 00:00
System.out.println(convertTo24HoursFormat("12:00PM")); // 12:00
System.out.println(convertTo24HoursFormat("11:59PM")); // 23:59
System.out.println(convertTo24HoursFormat("9:30PM")); // 21:30
} catch (ParseException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
}
// Replace with KK:mma if you want 0-11 interval
private static final DateFormat TWELVE_TF = new SimpleDateFormat("hh:mma");
// Replace with kk:mm if you want 1-24 interval
private static final DateFormat TWENTY_FOUR_TF = new SimpleDateFormat("HH:mm");
public static String convertTo24HoursFormat(String twelveHourTime)
throws ParseException {
return TWENTY_FOUR_TF.format(
TWELVE_TF.parse(twelveHourTime));
}
}
Now that I think about it, SimpleDateFormat, H h K k can be confusing.
Cheers.
You need to use: SimpleDateFormat
And can refer this tutorial: Formatting hour using SimpleDateFormat
Example:
//create Date object
Date date = new Date();
//formatting hour in h (1-12 in AM/PM) format like 1, 2..12.
String strDateFormat = "h";
SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
System.out.println("hour in h format : " + sdf.format(date));
I wouldn't reinvent the wheel (unless you are doing this as a school project or some such).
Just get a date object out of your time stamp and then you can generate whatever format you want with this: SimpleDateFormat
[edited to address your specific request]
if you absolutely need to work from your own unique strings, then you'll do something like this (I don't know exactly what your strings look like... you're using offsets like 85, which means nothing out of context).
I didn't check this for bugs, but this is approximately what you want...
myStr = timestampString.toLowerCase(); //something like 8:30am
boolean add12 = (myStr.indexOf("pm") != -1)?true:false;
//convert hour to int
int hour = Integer.parseInt(myStr.split(":")[0]);
int minutes = Integer.parseInt( myStr.split(":")[1].replaceAll("\\D+","").replaceAll("^0+","") ); //get the letters out of the minute part and get a number out of that, also, strip out leading zeros
int militaryTime = hour + (add12)? 12:0;
if(!add12 && militaryTime == 12)
militaryTime = 0; //account for 12am
//dont' forget to add the leading zeros back in as you assemble your string
With Joda Time, the code looks like:
DateTimeFormatter formatter12 = DateTimeFormat.forPattern("K:mma");
DateTime begin = formatter12.parseDateTime(beginTime);
DateTime end = formatter12.parseDateTime(endTime);
DateTimeFormatter formatter24 = DateTimeFormat.forPattern("k:mma");
String begin24 = formatter24.print(begin);
String end24 = formatter24.print(end);
I should like to contribute the modern answer
DateTimeFormatter twelveHourFormatter = DateTimeFormatter.ofPattern("h:mma", Locale.ENGLISH);
String time = "8:30AM - 9:30PM";
String[] times = time.split(" - ");
LocalTime start = LocalTime.parse(times[0], twelveHourFormatter);
System.out.println(start.toString());
LocalTime end = LocalTime.parse(times[1], twelveHourFormatter);
System.out.println(end.toString());
This prints:
08:30
21:30
I am using java.time, the modern Java date and time API. The SimpleDateFormat class used in many of the other answers is long outdated and was always troublesome. java.time is so much nicer to work with than the date-time classes from the 1990’s. A LocalTime is a time of day without a date (and without time zone), so suits your need much better than an old-fashioned Date.
Link: Oracle tutorial: Date Time explaining how to use java.time.
24 hour time adds 12 to any time greater than 12pm so that 1pm is 13 and so on until 24 or 12am. Here is the sudo code:
if(hour <= 12)
{
hour = hour + 12;
}
All the below lines will works when
String str="07:05:45PM";
and when you call timeConversion(str) and want to convert to 24 hours format..
public class TimeConversion {
private static final DateFormat TWELVE_TF = new SimpleDateFormat("hh:mm:ssa");
private static final DateFormat TWENTY_FOUR_TF = new SimpleDateFormat("HH:mm:ss");
static String timeConversion(String s) {
String str = null;
try {
str= TWENTY_FOUR_TF.format(
TWELVE_TF.parse(s));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return str;
}
public static void main(String[] args) throws ParseException {
String str="07:05:45PM";
System.out.println(timeConversion(str));
}
}