I would like to convert "9:00 am – 11:00 pm" -> "9:00 - 23:00", how can I do that? What I've tried so far:
if(input.contains("am")) { //This because I have a string with other kind of items too (not only these interval of hours but names, etc)
DateFormat df = new SimpleDateFormat("h:mm a – h:mm a");
DateFormat outputformat = new SimpleDateFormat("HH:mm - HH:mm");
Date date = null;
String output = null;
date= df.parse(input);
input = outputformat.format(date);
System.out.println("Output: "+output);
}
but the output is wrong, in the example 23:00 - 23:00 because it doesn't recognize the first and the second hour
I tried also something like:
DateFormat df = new SimpleDateFormat("h:mm a" +" - "+ "h:mm a");
DateFormat outputformat = new SimpleDateFormat("HH:mm"+" - "+ "HH:mm");
but I got a parse error then
Try this:
String dateToParse = "9:00 am – 11:00 pm";
String splitDate[] = dateToParse.split("–");
DateFormat df = new SimpleDateFormat("h:mm a");
DateFormat outputformat = new SimpleDateFormat("HH:mm");
Date date1 = null, date2 = null;
String output1 = null, output2 = null;
try {
date1 = df.parse(splitDate[0].trim());
date2 = df.parse(splitDate[1].trim());
} catch (ParseException e) {
e.printStackTrace();
}
output1 = outputformat.format(date1);
output2 = outputformat.format(date2);
System.out.println("Output: " + output1 + " – " + output2);
Go object-oriented and use java.time
Don’t convert your interval from one string format to another. Design an Interval class for storing and manipulating your time intervals. I suggest that you include a convenience constructor that accepts a string and a toString method that produces your desired format.
I furthermore recommend that you use java.time, the modern Java date and time API, for your time work.
public class Interval {
private static final String middlePart = " – ";
private static final DateTimeFormatter amPmFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("h:mm a")
.toFormatter(Locale.ENGLISH);
private LocalTime begin;
private LocalTime end;
public Interval(String intervalString) {
String[] timeStrings = intervalString.split(middlePart);
if (timeStrings.length != 2) {
throw new IllegalArgumentException("Improper format");
}
begin = LocalTime.parse(timeStrings[0], amPmFormatter);
end = LocalTime.parse(timeStrings[1], amPmFormatter);
}
#Override
public String toString() {
return "" + begin + middlePart + end;
}
}
To try it out:
Interval testInterval = new Interval("9:00 am – 11:00 pm");
System.out.println(testInterval);
Output is:
09:00 – 23:00
What went wrong in your code?
Date is the completely wrong class to use for your interval. The class is poorly designed and long outdated. A date represents a point in time, not a time of day and certainly not an interval of two times of day.
SimpleDateFormat — a notorious troublemaker of a class — tried to parse your string into a time of January 1, 1970 in your time zone. It should have objected because a time on that day cannot be both 9 AM and 11 PM — you were contradicting yourself. But no, SimpleDateFormat gives you one of those times, keeps its mouth shut and pretends all is well. Possibly an attempt to be nice, but if so, IMHO a completely misunderstood attempt.
Link
Oracle tutorial: Date Time explaining how to use java.time.
I am working on an Android app that frequently travels from Time Zone to TZ. I am getting various errors with times and TZs. The latest error is, when I load the flat file with times (see below), everything looks good. When I save the app environment (aka all variables/objects to sharedprefs), stop and then restart the app the time displayed is no longer local but UTC.
I began developing the app just using the default/local TZ. However, this became very complicated with DST and various TZs. Therefore my current approach is to store time in the app in UTC, and calculate differences between UTC times as needed. Then convert the UTC-stored time to the local TZ on-demand for user interaction.
I recognize there are many posts related to android time. I think I have read most if not all on java.util.date and Joda. However, I am still stuck. So, here goes...
I have 3 sources of time for the app. 1) I read in UTC Strings from a flat file 2) I get milliseconds since the Epoch for system time stamp (in UTC). 3) I get UTC in a string via a rest API. The app does numerous calculations between the 3 categories such as time difference, add time, etc. Below I will post my code for each of these
1 - Convert string UTCs that come from a file
public static Date string2date(String strformat, String strdate){
Date tdate = timestamp();
TimeZone tz = TimeZone.getDefault() ;
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
SimpleDateFormat formatter = new SimpleDateFormat(strformat);
formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateInString = strdate;
try {
tdate = formatter.parse(dateInString);
} catch (ParseException e) {
e.printStackTrace();
}
return tdate;
}
2 - Get milliseconds since Epoch
public static Date timestamp() {
Calendar localCalendar = Calendar.getInstance(TimeZone.getDefault());
//Date currentTime = localCalendar.getTime();
Date currentTime = GetUTCdatetimeAsDate();
return currentTime;
public static Date GetUTCdatetimeAsDate()
{
//note: doesn't check for null
return StringDateToDate(GetUTCdatetimeAsString());
}
public static String GetUTCdatetimeAsString()
{
final SimpleDateFormat sdf = new SimpleDateFormat(longdt);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
final String utcTime = sdf.format(new Date());
return utcTime;
}
public static Date StringDateToDate(String StrDate)
{
Date dateToReturn = null;
SimpleDateFormat dateFormat = new SimpleDateFormat(longdt);
try
{
dateToReturn = (Date)dateFormat.parse(StrDate);
}
catch (ParseException e)
{
e.printStackTrace();
}
return dateToReturn;
}
3 - Get UTC in a string via a rest API (Format is "2017-02-10T01:09:00Z")
try {
Calendar tempCal = ISO8601.toCalendar(dateLocal);
Log.e (" fbu "," fsutc " + tempCal.getTime() );
ISODepDate = tempCal.getTime();
tempCal = ISO8601.toCalendar(dateLocal2);
ISOArrDate = tempCal.getTime();
//ab.setTimeZone(PST);
Log.e (" fbu "," fsutc " + dateLocal + " / " + dateLocal2);
Log.e (" fbu "," fsutc " + ISODepDate + " / " + ISOArrDate);
}
catch (Exception a){
int aa = 1;
Log.e (" exception "," a " + a);
}
public static Calendar toCalendar(final String iso8601string)
throws ParseException {
Calendar calendar = GregorianCalendar.getInstance();
TimeZone tz = TimeZone.getDefault() ;
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
String s = iso8601string.replace(".000Z", "+00:00");
try {
s = s.substring(0, 22) + s.substring(23); // to get rid of the ":"
} catch (IndexOutOfBoundsException e) {
throw new ParseException("Invalid length", 0);
}
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(s);
calendar.setTime(date);
return calendar;
}
4 - Finally, here is what I am using to "Display" the above 3 time categories in local time.
public String UTCtoLocal(Date indate, Boolean formatLong) {
Date utcDate = indate;
String result;
//Log.e( " utc "," indate " + indate);
/*utcDate = your own initialization here;*/
Date localDate = new Date(utcDate.getTime() + TimeZone.getDefault().getRawOffset());
//Log.e( " utc "," localdate " + localDate);
if (formatLong){
result = longd.format(localDate);
} else {
result = shortt.format(localDate);
}
return result;
The questions are, given the expectation that I store in UTC and display in Local, a) Have I implemented items 1-4 correctly? b) Will the above code actually store the times in UTC and display in local?
After flat file load everything looks good. After restart the times are displayed in UTC vs Local.
I am trying to display Date based on timezone.
If I change my system time zone to US pacific time zone, today's date is displayed correctly. If I want to display 2000-01-01 output shows as 12/31/1969.
Can you please let me know if I have to make any change in system settings or java settings?.
Below is the example code:
package timezoneexample;
import java.text.DateFormat;
import java.util.Date;
import java.util.TimeZone;
public class TimezoneExample {
public static void main(String args[]) {
DateFormat dateFormat = null;
String datePattern = null;
char dateSeperator = '/';
try {
datePattern = "MM/dd/yyyy";
if (datePattern.length() <= 0)
throw new java.util.MissingResourceException(
"Didn't find date format", "", "");
boolean hasSeperatorAlready = false;
for (int i = 0; i < datePattern.length(); i++)
if (!Character.isLetter(datePattern.charAt(i)))
if (hasSeperatorAlready)
throw new java.util.MissingResourceException(
"Unvalid date format", "", "");
else
dateSeperator = datePattern.charAt(i);
} catch (java.util.MissingResourceException mre) {
System.out.println(mre);
}
dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM);
if (datePattern.length() > 0
&& dateFormat instanceof java.text.SimpleDateFormat) {
java.text.SimpleDateFormat sdf = (java.text.SimpleDateFormat) dateFormat;
sdf.applyPattern(datePattern);
}
dateFormat.setTimeZone(java.util.TimeZone.getDefault());
// enter DOB
Date dob = new Date(2000 - 01 - 01);
Date today = new Date();
String timeZone = System.getProperties().getProperty("user.timezone");
TimeZone tZone = TimeZone.getTimeZone(timeZone);
System.out.println("Timezone : " + tZone);
dateFormat.setTimeZone(tZone);
System.out.println("Date Of Birth : " + dateFormat.format(dob));
System.out.println("Date in Displayed as per Timezone : "
+ dateFormat.format(today));
}
}
Output:
Timezone : sun.util.calendar.ZoneInfo[id="America/Los_Angeles",offset=-28800000,dstSavings=3600000,useDaylight=true,transitions=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-28800000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]]
Date Of Birth : 12/31/1969
Date in Displayed as per Timezone : 01/07/2015
Your error is here:
Date dob = new Date(2000 - 01 - 01);
This will be interpreted as:
Date dob = new Date(1998);
This will invoke the Date(long date) constructor, resulting in a date near 1970/01/01.
What you most probably want is:
Date dob = new Date(2000, 1, 1);
new Date(...) requires a long value, expressing the number of milliseconds since 1/1/1970. You're specifying 2000 - 1 - 1. This is NOT "year 2000, month 1 and day 1", it is a numeric expression equal to 1998 milliseconds.
To create a date based on year/month/day, use a Calendar:
Calendar c = Calendar.getInstance();
c.set(y, m-1 /* 0-based */, d); // e.g. c.set(2000, 0, 1);
return c.getTime();
I haven't programmed in Java for many years, but I now have to change a program I wrote some time ago. In this program I need to read a QIF file and find the qif record with the maximum date (Dmm-dd-yyyy).
I could not get this to work in my program so I wrote a simple test to demonstrate the problem I am having. I think there are other ways to do this, like lists and collections. But I still want to know why using SimpleDateFormat won't work. Notice in the output that this method produces the max for July but seems to ignore all August dates.
Thanks, Mike
import java.text.SimpleDateFormat;
import java.util.Date;
class DateParser {
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("mm-dd-yyyy");
Date nextDate = null;
Date maxDate = null;
String nextStrDate = null;
String maxStrDate = null;
//Fill date array.
String date[] = {"07-14-2014","07-22-2014","07-31-2014",
"08-01-2014","08-04-2014","08-06-2014"};
try {
//Start with early maximum date.
maxDate = sdf.parse("01-01-1800");
// Find Max date in array.
for (int i=0; i<6; ++i) {
nextStrDate = date[i];
nextDate = sdf.parse(nextStrDate);
if(nextDate.after(maxDate)){
maxStrDate = nextStrDate;
maxDate = nextDate;
}
System.out.println( "Next Date = " + nextStrDate);
}
System.out.println("\nMax Date = " + maxStrDate);
} catch (Exception e) {
System.out.println("Got error:" + e);
}
}
}
OUTPUT
Next Date = 07-14-2014
Next Date = 07-22-2014
Next Date = 07-31-2014
Next Date = 08-01-2014
Next Date = 08-04-2014
Next Date = 08-06-2014
Max Date = 07-31-2014
From the Java Docs....
m Minute in hour
What you want is
M Month in year
Change mm-dd-yyyy to MM-dd-yyyy
You format is incorrect, this
SimpleDateFormat sdf = new SimpleDateFormat("mm-dd-yyyy");
should be
SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
because (per the SimpleDateFormat documentation),
Letter Date or Time Component Presentation Examples
...
M Month in year Month July; Jul; 07
...
m Minute in hour Number 30
I have followed method getDiffDateMap that calculates difference between 2 dates and returns Map of Integers that represent milliseconds, seconds, minutes, hours, days, months and years respectively.
public static Map<Integer, String> getDiffDateMap(String dateA, String dateB) {
Calendar cal = Calendar.getInstance();
Map<Integer,String> out = new LinkedHashMap<Integer, String>();
long timeInMillA = 0;
long timeInMillB = 0;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date convertedDateA;
Date convertedDateB;
try {
convertedDateA = dateFormat.parse(dateA);
cal.setTime(convertedDateA);
timeInMillA = cal.getTimeInMillis();
convertedDateB = dateFormat.parse(dateB);
cal.setTime(convertedDateB);
timeInMillB = cal.getTimeInMillis();
} catch (ParseException e) {
e.printStackTrace();
}
long mili = timeInMillB - timeInMillA;
long sec = mili/1000;
long min = sec/60;
long hour = min/60;
long day = hour/24;
long week = day/7;
long month = day/31; // ????
long year = month/12;
out.put(7, mili + "");
out.put(6, sec + "");
out.put(5, min + "");
out.put(4, hour + "");
out.put(3, day + "");
out.put(2, week + "");
out.put(1, month + "");
out.put(0, year + "");
return out;
}
My problem is to calculate month from actual day count:
long month = day/31; // or 30
For example:
Map<Integer,String> out = getDiffInMillsec("2012-9-01 20:9:01", "2012-10-01 20:10:01");
System.out.println(Arrays.asList(out));
I get output: [{7=2592060000, 6=2592060, 5=43201, 4=720, 3=30, 2=4, 1=0, 0=0}] where 1 is month count and its 0. because difference is 30 days only. What flow need I add to fix this problem? Any suggestions?
I have followed method getDiffDateMap that calculates difference between 2 dates and returns Map of Integers that represent milliseconds, seconds, minutes, hours, days, months and years respectively.
Don't reinvent the wheel :)
Joda Time has code to do all this and more. For example:
LocalDateTime start = ...;
LocalDateTime end = ...;
Period difference = new Period(start, end, PeriodType.yearMonthDayTime());
int months = difference.getMonths(); // etc
Note that you can't get at the number of months when you've just converted the different to a number of milliseconds - as the number of months will depend on the start/end date. (30 days may or may not be a month, for example...)
I'd strongly advise you to use Joda Time throughout your Java code, in preference to java.util.*. It's a much better API, and one which will hopefully mean you rarely-if-ever need to write your own date/time handling code.
I woud suggest to use JodaTime#Months
This has a functions such as :
static Months monthsBetween(ReadableInstant start, ReadableInstant end)
Creates a Months representing the number of whole months between the two specified datetimes.
static Months monthsBetween(ReadablePartial start, ReadablePartial end)
Creates a Months representing the number of whole months between the two specified partial datetimes.
I just want to conclude all what we talked before and with help of Jon Skeet, here is an answer, I used JodaTime and new Period per date value:
import org.joda.time.LocalDateTime;
import org.joda.time.Period;
import org.joda.time.PeriodType;
....
public static Map<Integer, String> getDateTimeDiffMap(String dateA, String dateB) {
Calendar cal = Calendar.getInstance();
Map<Integer,String> out = new LinkedHashMap<Integer, String>();
long timeInMillA = 0;
long timeInMillB = 0;
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
Date convertedDateA;
Date convertedDateB;
try {
convertedDateA = dateFormat.parse(dateA);
cal.setTime(convertedDateA);
timeInMillA = cal.getTimeInMillis();
convertedDateB = dateFormat.parse(dateB);
cal.setTime(convertedDateB);
timeInMillB = cal.getTimeInMillis();
} catch (ParseException e) {
e.printStackTrace();
}
LocalDateTime startA = new LocalDateTime(timeInMillA);
LocalDateTime startB = new LocalDateTime(timeInMillB);
Period difference = new Period(startA, startB, PeriodType.days());
int day = difference.getDays();
difference = new Period(startA, startB, PeriodType.months());
int month = difference.getMonths();
difference = new Period(startA, startB, PeriodType.years());
int year = difference.getYears();
difference = new Period(startA, startB, PeriodType.weeks());
int week = difference.getWeeks();
difference = new Period(startA, startB, PeriodType.hours());
int hour = difference.getHours();
difference = new Period(startA, startB, PeriodType.minutes());
long min = difference.getMinutes();
difference = new Period(startA, startB, PeriodType.seconds());
long sec = difference.getSeconds();
//difference = new Period(startA, startB, PeriodType.millis());
long mili = timeInMillB - timeInMillA;
out.put(7, mili + "");
out.put(6, sec + "");
out.put(5, min + "");
out.put(4, hour + "");
out.put(3, day + "");
out.put(2, week + "");
out.put(1, month + "");
out.put(0, year + "");
return out;
}
For example for "01-09-2012 20:9:01", "01-10-2012 20:9:01" I get output:
year=0;
month = 1;
day=30;
hour=720;
...
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*.
Also, quoted below is a notice from the home page of Joda-Time:
Note that from Java SE 8 onwards, users are asked to migrate to java.time (JSR-310) - a core part of the JDK which replaces this project.
Solution using java.time, the modern Date-Time API:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(getDiffDateMap("2012-9-01 20:9:01", "2012-10-01 20:10:01"));
}
public static Map<Integer, String> getDiffDateMap(String dateA, String dateB) {
Map<Integer, String> out = new LinkedHashMap<Integer, String>();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("u-M-d H:m:s", Locale.ENGLISH);
LocalDateTime ldtA = LocalDateTime.parse(dateA, dtf);
LocalDateTime ldtB = LocalDateTime.parse(dateB, dtf);
out.put(7, String.valueOf(ChronoUnit.MILLIS.between(ldtA, ldtB)));
out.put(6, String.valueOf(ChronoUnit.SECONDS.between(ldtA, ldtB)));
out.put(5, String.valueOf(ChronoUnit.MINUTES.between(ldtA, ldtB)));
out.put(4, String.valueOf(ChronoUnit.HOURS.between(ldtA, ldtB)));
out.put(3, String.valueOf(ChronoUnit.DAYS.between(ldtA, ldtB)));
out.put(2, String.valueOf(ChronoUnit.WEEKS.between(ldtA, ldtB)));
out.put(1, String.valueOf(ChronoUnit.MONTHS.between(ldtA, ldtB)));
out.put(0, String.valueOf(ChronoUnit.YEARS.between(ldtA, ldtB)));
return out;
}
}
Output:
{7=2592060000, 6=2592060, 5=43201, 4=720, 3=30, 2=4, 1=1, 0=0}
ONLINE DEMO
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.
try {
String user = request.getParameter("uname");
out.println(user);
String pass = request.getParameter("pass");
out.println(pass);
java.sql.Date sqlDate = new java.sql.Date(new java.util.Date().getTime());
Class.forName( "com.mysql.jdbc.Driver" );
Connection conn = DriverManager.getConnection( "jdbc:mysql://localhost:3306/trans","root","root" ) ;
Statement st = conn.createStatement();
String sql = "insert into purch (cd,cust,dateof) values('" + user + "','" + pass + "', '" + sqlDate + "')";
st.executeUpdate(sql);
Date date = new Date();
String modifiedDate= new SimpleDateFormat("-MM-").format(date);
String dd = modifiedDate.toString();
String da = "ai";
out.println(dd);
PreparedStatement statement = conn.prepareStatement("select * from purch where dateof LIKE ? and cd = ?");
statement.setString(1,"%" + dd + "%");
statement.setString(2,"" + da + "");
ResultSet rs = statement.executeQuery();
if(rs != null) {
while(rs.next()) {
out.println(rs.getString("cd"));
out.println(rs.getString("cust"));
out.println(rs.getString("dateof"));
}
}
}catch(Exception e) {
System.out.println(e.toString());
}