SimpleDateFormat parsing date differently on some android devices - java

I am parsing the date as:
public class Consts{
public static final SimpleDateFormat DATE_FORMATTER_WITHOUT_TIME_ZONE = new SimpleDateFormat(
"yyyy-MM-dd HH:mm");
public static final SimpleDateFormat DATE_FORMATTER_2 = new SimpleDateFormat(
"MM-dd-yyyy HH:mm:ss ZZZZ");
}
cDate = new GregorianCalendar();
sDate = new GregorianCalendar();
eDate = new GregorianCalendar();
if (mStartTimeTV.getText().toString().equals("Now")) {
sDate.setTime(cDate.getTime());
} else {
sDate.setTime(Consts.DATE_FORMATTER_WITHOUT_TIME_ZONE
.parse(mStartTimeTV.getText().toString()));
}
if (!mEndTimeTV.getText().toString().equals("")) {
eDate.setTime(Consts.DATE_FORMATTER_WITHOUT_TIME_ZONE
.parse(mEndTimeTV.getText().toString()));
} else {
eDate.setTime(sDate.getTime());
// eDate = sDate;
}
And then i format the date as below before sending it to the server.:
request.addProperty("StartTime",
Consts.DATE_FORMATTER_2.format(sDate.getTime()));
request.addProperty("EndTime",
Consts.DATE_FORMATTER_2.format(eDate.getTime()));
But the thing is that on devices running 4.1.2 it is sending the date as:
Start Date: 03-23-2015 21:17:20 +0500
End Date : 10-23-2015 21:15:00 +0500
which throws exception on the server side.
But on the other devices it is sending dates as:
Start Date: 03-23-2015 21:12:13 GMT+05:00
End Date : 03-23-2015 21:16:00 GMT+05:00
which is required.
Am i doing something wrong? How can i prevent this problem so that all devices sends the same dates. (for example 03-23-2015 21:16:00 GMT+05:00)

The difference is caused by different locales set up on devices.
To mitigate the locale differences, you should use particular locale while formatting the date string. Here is a sample from my code, solving the same issue:
new SimpleDateFormat(C.FORMAT_DATETIMEZ, Locale.US).format(new Date(time))

You can extend SimpleDateFormat and override its format(...) function as following:
public class ExSimpleDateFormat extends SimpleDateFormat{
private static final long serialVersionUID = -8275126788734707527L;
public ExSimpleDateFormat() {
super();
}
public ExSimpleDateFormat(String string, Locale us) {
super(string, us);
}
#Override
public StringBuffer format(Date date, StringBuffer toAppendTo, java.text.FieldPosition pos)
{
final StringBuffer buf = super.format(date, toAppendTo, pos);
buf.insert(buf.length() - 2, ':');
return buf;
};
}
And execute following code:
Calendar ca = Calendar.getInstance();
ca.setTimeInMillis(System.currentTimeMillis());
ExSimpleDateFormat exSimpleDateFormat = new ExSimpleDateFormat("dd-MM-yyyy HH:mm:ss 'GMT'Z", Locale.US);
exSimpleDateFormat.setTimeZone(ca.getTimeZone()); //your device timezone which can be GMT+xx:yy or GMT-xx:yy
String desiredTime = exSimpleDateFormat.format(ca.getTime());
Output would be like: 23-03-2015 23:12:52 GMT+05:00
Let me know if it helps.
Thanks

Related

Android: how to get the timezone string in the format specified here

How can I obtain the timezone format and return the string like so
https://msdn.microsoft.com/en-us/library/gg154758.aspx - column Time zone name,
for example "SA Pacific Standard Time"
or worse comes to worst, how can I obtain it like so: (UTC-05:00) Bogota, Lima, Quito, or at least (UTC-05:00)
so that I can manually match it to the former String if I put them all in a map?
Have you tried?
TimeZone tz = TimeZone.getDefault();
System.out.println("TimeZone "+tz.getDisplayName(false, TimeZone.SHORT)+" Timezon id :: " +tz.getID());
Result be if your device happens to be in Australia
TimeZone GMT+09:30 Timezon id :: Australia/Darwin
This should return UTC as a String and Date object. You can change the date format.
static final String DATEFORMAT = "yyyy-MM-dd HH:mm:ss"
public static Date getUTCdatetimeAsDate()
{
//note: doesn't check for null
return stringDateToDate(GetUTCdatetimeAsString());
}
public static String getUTCdatetimeAsString()
{
final SimpleDateFormat sdf = new SimpleDateFormat(DATEFORMAT);
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(DATEFORMAT);
try
{
dateToReturn = (Date)dateFormat.parse(StrDate);
}
catch (ParseException e)
{
e.printStackTrace();
}
return dateToReturn;
}
This might be irrelevant (don't know if Android fully supports java-8), but you can do it using standard java api:
ZonedDateTime dateTime = ZonedDateTime.parse("2007-12-03T10:15:30+01:00[Asia/Tokyo]");
System.out.println(dateTime); // 2007-12-03T10:15:30+09:00[Asia/Tokyo]
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("(O) z");
System.out.println(dateTime.format(formatter)); // (GMT+9) JST

Android DateFormat for AM/PM differs between devices

I am formatting dates like this:
public static String toFormattedDate(#NonNull Time time, String toFormat) {
mDateFormat = new SimpleDateFormat(toFormat);
Date date = new Date();
date.setTime(time.toMillis(true));
return mDateFormat.format(date);
}
and the format I am using is:
public static final String TIME = "hh:mm a";
But it differs between the two devices that I am using for testing...
Nexus 10:
Nexus 5X:
How can I format it uniformly between devices?
You may either have to use either the 24 hour value to determine what to append so that you can add the format you desire.
public static final String TIME = "hh:mm";
and then
String ampm = Integer.parseInt(time.valueOf("hh")) >= 12 ? "PM" : "AM";
...
return mDateFormat.format(date)+" "+ampm;
Or if you feel lazy you can just do without changing the value of TIME:
return mDateFormat.format(date).toUpperCase().replace(".","");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String currentDateandTime = sdf.format(new Date());

trying to parse/formate date with timezone using joda-time/java

I am trying to parse the date to look like 03-23-2015 21:16:00 GMT+05:00 using joda-time but i am not able to achieve it, however it is working fine with SimpleDateFormat but for some reason i want to use Joda-Time (see my question on SO.)
Please note that i don't want to hardcode timezone to GMT+05:00 but i want to set the user's default timezone.
I am trying it as:
public class Consts{
public static final DateTimeFormatter DATE_FORMATTER_2 = DateTimeFormat
.forPattern("MM-dd-yyyy HH:mm:ss z");
public static final DateTimeFormatter DATE_FORMATTER_TEMP_1 = DateTimeFormat
.forPattern("MM-dd-yyyy HH:mm:ss Z");
}
And then i am using these formatters as:
cDate = new LocalDateTime(DateTimeZone.getDefault());
sDate = new LocalDateTime(DateTimeZone.getDefault());
eDate = new LocalDateTime(DateTimeZone.getDefault());
if (mStartTimeTV.getText().toString().equals("Now")) {
sDate = cDate;
} else {
sDate = Consts.DATE_FORMATTER_WITHOUT_TIME_ZONE
.parseLocalDateTime(mStartTimeTV.getText().toString());
}
if (!mEndTimeTV.getText().toString().equals("")) {
eDate = Consts.DATE_FORMATTER_WITHOUT_TIME_ZONE
.parseLocalDateTime(mEndTimeTV.getText().toString());
} else {
eDate = sDate;
}
And while sending the dates to the server i am formatting them as:
String s0 = Consts.DATE_FORMATTER_2.print(sDate);
String s = Consts.DATE_FORMATTER_2.withZone(
DateTimeZone.getDefault()).print(sDate);
String s1 = Consts.DATE_FORMATTER_TEMP_1.print(sDate);
But the output is always: 03-24-2015 16:07:23
I have also tried with ZZZZ but no luck.
LocalDateTime doesn't have a time zone, so there is nothing to format. You should use DateTime instead, which you can obtain using LocalDateTime.toDateTime(timeZone).

issue with date and time zone how to get date without time zone?

I tried to do convert between date in Tics to UTC date time format - 'YYYY-MM-DDThh:mm:ss'
public static DateFormat getFormat() {
String systemLocale = System.getProperty("user.language"); //$NON-NLS-1$
Locale locale = new Locale(systemLocale);
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale);
return dateFormat;
}
public static Object getFormatedValue(Object value) {
String updated = (strValue).replaceAll(pattern, "$1"); //$NON-NLS-1$
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(Long.parseLong(updated));
return getFormat().format(new Date(calendar.getTimeInMillis()));
}
public static Object getOdataValue(Object value) throws ParseException {
DateFormat dateFormat = getFormat();
Date parse = dateFormat.parse(value.toString());
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(parse.getTime());
return "\"/Date(" + calendar.getTimeInMillis() + ")/\""; //$NON-NLS-1$ //$NON-NLS-2$
}
The problem that I got the result of dtae time with UTC for example -
1393358368000 = Tue, 25 Feb 2014 19:59:28 GMT
Your time zone: 2/25/2014 9:59:28 PM GMT+2
The result from this code is 2/25/2014 21:59:28 PM
How I can get the result without time zone ? in this case I want that the result will be ue, 25 Feb 2014 19:59:28 GMT
Can I have tick and got different result with and without UTC ?
It's not entirely clear what you're asking, but if all you want is to make your DateFormat use UTC, that's easy:
public static DateFormat getFormat() {
String systemLocale = System.getProperty("user.language"); //$NON-NLS-1$
Locale locale = new Locale(systemLocale);
DateFormat dateFormat = DateFormat.getDateTimeInstance(
DateFormat.MEDIUM, DateFormat.MEDIUM, locale);
dateFormat.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
return dateFormat;
}
(Any reason you're not using Locale.getDefault() for the default locale, by the way? Or letting the DateFormat pick it itself?)
Also note that you're creating calendars for no reason at all. Your getFormattedValue and getOdataValue methods can be simplified to:
public static Object getFormattedValue(Object value) {
String updated = (strValue).replaceAll(pattern, "$1"); //$NON-NLS-1$
long millis = Long.parseLong(updated);
return getFormat().format(new Date(millis));
}
public static Object getOdataValue(Object value) throws ParseException {
DateFormat dateFormat = getFormat();
Date parsedDate = dateFormat.parse(value.toString());
return "\"/Date(" + date.getTime() + ")/\""; //$NON-NLS-1$ //$NON-NLS-2$
}

Formatting a Date of type String using a Formatter Java

Is it possible to do format a date of type String using a date formatter? I want to store my Date and Time in the Event class as Strings so that I don't need to convert the Strings loaded from a MYSQL database (using the types DATE and TIME) back into Date types so they can be stored in new Event objects. MySQL only accepts DATE in the format of YYYY-MM-DD and TIME in the format of HH:MM:SS but i want these to be formatted differently when i go to print them out in my program.
When i run this code i get an Cannot format given Object as a Date at java.text.DateFormat.format(Unknown Source) error. If i try using parse() it won't compile because it only accepts Dates.
Main class
public Main() {
ArrayList<Event> events = new ArrayList<Event>();
private SimpleDateFormat timeFormat = new SimpleDateFormat("HH:MM:SS");
private SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-DD");
//Stores current time and date
Date date;
Date time;
String d = "";
String t = "";
d= dateFormat.parse(date);
t= timeFormat.parse(time);
events.add(d, t);
//Print out newly formatted date and time when loaded from mysql
System.out.println(events.get(0).printDate());
System.out.println(events.get(0).printTime());
}
Events class
public class Event {
private String date;
private String time;
public Event(String d, String t) {
date = d;
time = t;
}
public String printDate() {
SimpleDateFormat format = new SimpleDateFormat("DD/MM/YYYY");
String newDate = format.format(date);
return newDate;
}
public String printTime() {
SimpleDateFormat format = new SimpleDateFormat("HH:mm");
String newTime = format.format(time);
return newTime;
}
}
In Event, you should use Date type for date and time field.
This is a more appropriate representation for date and time value. And with them, you can use DateFormat to do whatever formatting you want
(It will be even better to use Joda time LocalDate and LocalTime for your date and time, but that's a bit off topic)
You can't format your dates because they are String objects and SimpleDateFormat needs Date objects.
You should consider a different way of storing them (either as Date or Calendar). See below:
public class Event
{
private Date date;
private Date time;
public Event(String d, String t)
{
String[] details = d.split("\\-");
Calendar c = Calendar.getInstance();
c.set(Integer.parseInt(details[0]), Integer.parseInt(details[1]), Integer.parseInt(details[2]));
date = c.getTime();
details = t.split(":");
c.set(Integer.parseInt(details[0]), Integer.parseInt(details[1]), Integer.parseInt(details[2]));
time = c.getTime();
}
public String printDate()
{
SimpleDateFormat format = new SimpleDateFormat("dd/MM/YYYY");
String newDate = format.format(date);
return newDate;
}
// rest of you class can stay the way it is
}
You can format java.util.Date or java.sql.Date (which is subclass of java.util.Date) using date formatter, eg:
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
String dateStr = df.format(date);
Using jdbc ResultSet getDate() method you can obtain java.sql.Date object which you can print in any format using method above
Similar techniques can also be used to parse string in any format into a java.util.Date object
Date date = df.parse(dateStr);
Check the javadoc for the right formatting codes. Try this:
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");

Categories

Resources