Unable to detect cause of application crash. Variables StartDate and lastTimeCalculateValues are long.
Cursor c = MyApplicationExtendsClass.database.rawQuery("SELECT * FROM " + MyApplicationExtendsClass.locationTableName + " WHERE [Date] >= '" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US).format(StartDate) + "' AND [Date] <= '" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US).format(lastTimeCalculateValues) + "' ORDER BY Id ASC", null);
Crash output from Google play console, 5% of active users and that is all I get.
android.database.sqlite.SQLiteException:
at android.database.sqlite.SQLiteConnection.nativePrepareStatement (Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement (SQLiteConnection.java:948)
at android.database.sqlite.SQLiteConnection.prepare (SQLiteConnection.java:559)
at android.database.sqlite.SQLiteSession.prepare (SQLiteSession.java:603)
at android.database.sqlite.SQLiteProgram.<init> (SQLiteProgram.java:63)
at android.database.sqlite.SQLiteQuery.<init> (SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query (SQLiteDirectCursorDriver.java:46)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory (SQLiteDatabase.java:1493)
at android.database.sqlite.SQLiteDatabase.rawQuery (SQLiteDatabase.java:1427)
at my.packagename.MainActivity.calculateValuesFinalFromDb (MainActivity.java:4013)
at my.packagename.MainActivity.access$1800 (MainActivity.java:152)
at my.packagename.MainActivity$CalculateValuesTimer.run (MainActivity.java:4112)
at java.util.TimerThread.mainLoop (Timer.java:562)
at java.util.TimerThread.run (Timer.java:512)
SQLite docs for DateTime SQLite docs
A time string can be in any of the following formats:
YYYY-MM-DD
YYYY-MM-DD HH:MM
YYYY-MM-DD HH:MM:SS
YYYY-MM-DD HH:MM:SS.SSS
YYYY-MM-DDTHH:MM
YYYY-MM-DDTHH:MM:SS
YYYY-MM-DDTHH:MM:SS.SSS
HH:MM
HH:MM:SS
HH:MM:SS.SSS
now
DDDDDDDDDD
Documentation says yyyy-MM-dd HH:mm:ss.SSS can be used
Try to change
SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US)
To
SimpleDateFormat("yyyy-MM-dd", Locale.US)
This is the default SQL format for dates.
And see my answer here: Can't get data from date to date SQLite
Update:
First part of your link:
SQLite supports five date and time functions as follows:
1. date(timestring, modifier, modifier, ...)
2. time(timestring, modifier, modifier, ...)
3. datetime(timestring, modifier, modifier, ...)
4. julianday(timestring, modifier, modifier, ...)
5. strftime(format, timestring, modifier, modifier, ...)
To get presicion in milliseconds you could use following conversion:
CAST((julianday('your_date') - 2440587.5)*86400000 As INTEGER)
Explanation:
julianday('your_date') returns number of days since noon in Greenwich on November 24, 4714 B.C.
julianday('your_date') - 2440587.5 returns number of days in Epoch time (1970)
*86400000 converts it to milliseconds (24* 60* 60* 1000)
Found here.
Then you can do Integer comparison with >= or also with BETWEEN .. AND ..
Related
This is continuation to one of my previous question where I am not able to parse the date which is resolved now. In the below code, I have a date string and I know the time zone for the date string even though the string itself doesn't contain it. Then I need to convert the date into EST time zone.
String clientTimeZone = "CST6CDT";
String value = "Dec 29 2014 11:36PM";
value=StringUtils.replace(value, " ", " ");
DateTimeFormatter df = DateTimeFormat.forPattern("MMM dd yyyy hh:mma").withZone(DateTimeZone.forID(clientTimeZone));
DateTime temp = df.parseDateTime(value);
System.out.println(temp.getZone().getID());
Timestamp ts1 = new Timestamp(temp.getMillis());
DateTime date = temp.withZoneRetainFields(DateTimeZone.forID("EST"));//withZone(DateTimeZone.forID("EST"));
Timestamp ts = new Timestamp(date.getMillis());
System.out.println(ts1+"="+ts);
When I am running the code I am expecting ts1 to remain same and ts to be up by 1 hr. But iam getting below which I don't understand. I thought EST is one hour ahead of CST and so if it is 11 in CST, it should be 12 in EST. Also there seems to be offset by about eleven and half hours. Any clues on what I am missing.
2014-12-30 11:06:00.0=2014-12-30 10:06:00.0
I think the below code will help you.
String clientTimeZone = "CST6CDT";
String toStimeZone = "EST";
String value = "Dec 29 2014 11:36PM";
TimeZone fromTimeZone = TimeZone.getTimeZone(clientTimeZone);
TimeZone toTimeZone = TimeZone.getTimeZone(toStimeZone);
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(fromTimeZone);
SimpleDateFormat sf = new SimpleDateFormat("MMM dd yyyy KK:mma");
Date date = sf.parse(value);
calendar.setTime(date);
System.out.println(date);
calendar.add(Calendar.MILLISECOND, fromTimeZone.getRawOffset() * -1);
if (fromTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
}
calendar.add(Calendar.MILLISECOND, toTimeZone.getRawOffset());
if (toTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, toTimeZone.getDSTSavings());
}
System.out.println(calendar.getTime());
Copied from : http://singztechmusings.wordpress.com/2011/06/23/java-timezone-correctionconversion-with-daylight-savings-time-settings/
The method withZoneRetainFields() preserves the fields in the timezone CST (= UTC-06) hence your local timestamp (as LocalDateTime) but combines it with a different timezone (EST = UTC-05) which is one hour ahead in offset and result in a different instant. You should it interprete it this way: The same local time happens one hour earlier in New York compared to Chicago.
The rule is to subtract positive offsets and to add negative offsets in order to make timestamp representations of instants comparable (normalizing to UTC offset).
Alternatively: Maybe you don't want this but want to preserve the instant instead of the local fields. In this case you have to use the method withZone().
Side notice: Effectively, you compare the instants represented by the variables temp and date and finally use your default timezone to print these instants in the JDBC-escape-format (explanation - you implicitly use Timestamp.toString()). I would rather recommend to use a dedicated instant formatter for this purpose or simpler (to have the offsets in focus):
System.out.println(temp.toInstant() + " = " + date.toInstant());
I want to get the current time in UTC. What I do so far is following (just for testing purposes):
DateTime dt = new DateTime();
DateTimeZone tz = DateTimeZone.getDefault();
LocalDateTime nowLocal = new LocalDateTime();
DateTime nowUTC = nowLocal.toDateTime(DateTimeZone.UTC);
Date d1 = nowLocal.toDate();
Date d2 = nowUTC.toDate();
L.d("tz: " + tz.toString());
L.d("local: " + d1.toString());
L.d("utc: " + d2.toString());
d1 is my local time, that's fine
d2 is my local time + 1, but should be local time - 1...
My local time zone is UTC+1 (according to the debug output and the list here: https://www.joda.org/joda-time/timezones.html)...
How do I correctly convert from one time zone to another (inclusive the millisecond representation)?
EDIT
I need the date/milliseconds... It's NOT about displaying the time correctly....
EDIT 2
Now, with the help of a comment and an answer, I tried following:
DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowLocal = new DateTime();
LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);
Date dLocal = nowLocal.toDate();
Date dUTC = nowUTC.toDate();
Date dUTC2 = nowUTC2.toDate();
L.d(Temp.class, "------------------------");
L.d(Temp.class, "tz : " + tz.toString());
L.d(Temp.class, "local : " + nowLocal + " | " + dLocal.toString());
L.d(Temp.class, "utc : " + nowUTC + " | " + dUTC.toString()); // <= WORKING SOLUTION
L.d(Temp.class, "utc2 : " + nowUTC2 + " | " + dUTC2.toString());
OUTPUT
tz : Europe/Belgrade
local : 2015-01-02T15:31:38.241+01:00 | Fri Jan 02 15:31:38 MEZ 2015
utc : 2015-01-02T14:31:38.241 | Fri Jan 02 14:31:38 MEZ 2015
utc2 : 2015-01-02T14:31:38.241Z | Fri Jan 02 15:31:38 MEZ 2015
What I wanted was, that the local date displays 15 o'clock and utc date displays 14 o'clock...
For now, this seems to work...
----- EDIT3 - Final solution -----
Hopefully, this is a good solution... I think, i respects all tipps i got...
DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowUTC = new DateTime(DateTimeZone.UTC);
DateTime nowLocal = nowUTC.withZone(tz);
// This will generate DIFFERENT Dates!!! As I want it!
Date dLocal = nowLocal.toLocalDateTime().toDate();
Date dUTC = nowUTC.toLocalDateTime().toDate();
L.d("tz : " + tz.toString());
L.d("local : " + nowLocal + " | " + dLocal.toString());
L.d("utc : " + nowUTC + " | " + dUTC.toString());
Output:
tz : Europe/Belgrade
local : 2015-01-03T21:15:35.170+01:00 | Sat Jan 03 21:15:35 MEZ 2015
utc : 2015-01-03T20:15:35.170Z | Sat Jan 03 20:15:35 MEZ 2015
You're making it far more complicated than you need to:
DateTime dt = new DateTime(DateTimeZone.UTC);
No conversion required at all. If you find you actually need to convert, you can use withZone. I'd suggest you avoid going via LocalDateTime, however, as that way you can lose information due to time zone transitions (two different instants can have the same local time in the same time zone, because clocks go back and repeat local time.
Having said all of this, for the sake of testability I personally like using a Clock interface which allows me to get the current time (e.g. as an Instant). You can then use dependency injection to inject a real system clock when running in production, and a fake clock with a preset time for tests. Java 8's java.time package has this idea built into it, btw.
You can also use the static method now which makes it even more readable
DateTime.now(DateTimeZone.UTC)
Use this
DateTime.now().withZone(DateTimeZone.UTC)
and if you want to format, you can use
DateTime.now().withZone(DateTimeZone.UTC).toString("yyyyMMddHHmmss")
Please try to listen to Jon Skeets good advise and comments. Here an additional explanation. Your edit-2 contains a mistake:
DateTimeZone tz = DateTimeZone.getDefault();
DateTime nowLocal = new DateTime();
LocalDateTime nowUTC = nowLocal.withZone(DateTimeZone.UTC).toLocalDateTime();
DateTime nowUTC2 = nowLocal.withZone(DateTimeZone.UTC);
Date dLocal = nowLocal.toDate();
Date dUTC = nowUTC.toDate();
Date dUTC2 = nowUTC2.toDate();
If you call toDate() on an object nowUTC of type LocalDateTime then you can get surprises - see javadoc. Joda-Time claims to use the same fields in java.util.Date as in nowUTC. What does this mean? Let's analyze:
nowUTC.toString() produces 2015-01-02T14:31:38.241 That is without timezone (note the missing Z at the end), so it is just a plain local timestamp. By context, we know it was generated in UTC. In your next step however, you convert it to a java.util.Date using the mentioned method above. This method combines the local timestamp with the system timezone (Belgrade) PRESERVING the FIELDS, hence CHANGING the instant. So you have finally miscorrected your instant. And your second line is wrong.
If you just want
utc date displays 14 o'clock
then don't use the questionable and misleading conversion method Joda-Time offers. Use instead a dedicated formatter with the pattern "EEE MMM dd HH:mm:ss zzz yyyy" or similar (Joda-Time offers DateTimeFormatter). Set the UTC-offset on this formatter and print. Done. Abandon completely any call of java.util.Date.toString(). This way, you don't even need to do any dangerous conversion at all.
From here: http://www.joda.org/joda-time/userguide.html#Changing_TimeZone
// get current moment in default time zone
DateTime dt = new DateTime();
// translate to London local time
DateTime dtLondon = dt.withZone(DateTimeZone.forID("Europe/London"));
The resulting value dtLondon has the same absolute millisecond time, but a different set of field values.
You can substitute `Europe/London' for the timezone you want (UTC). See this list of proper time zone names.
SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
// or SimpleDateFormat sdf = new SimpleDateFormat( "MM/dd/yyyy KK:mm:ss a Z" );
sdf.setTimeZone( TimeZone.getTimeZone( "UTC" ) );
System.out.println( sdf.format( new Date() )
);
Instead of System.out.println( sdf.format( new Date() ) put your local date
I fixed this with this converter
public class DateTimeConverter implements AttributeConverter<DateTime, Date> {
#Override
public Date convertToDatabaseColumn(DateTime attribute) {
return attribute == null ? null
: new Date(attribute
.withZone(DateTimeZone.UTC)
.withZoneRetainFields(DateTimeZone.getDefault())
.getMillis());
}
#Override
public DateTime convertToEntityAttribute(Date dbData) {
return dbData == null ? null
: new DateTime(dbData.getTime())
.withZoneRetainFields(DateTimeZone.UTC)
.withZone(DateTimeZone.getDefault());
}
}
Dates are stored as UTC and recovered with your current time zone
I am trying to create a date object(format : HH:MM) from a String Example 13:30(HH:MM). I want to save the HH:MM in MySql table but the below code enters some random value in the column (eg: '6828-00-00 00:00:00'). How can i store the date value in Mysql in the HH:MM format ?
Date date = null;
String afternoon = "13" +":" +"30";
String time = afternoon;
try {
date = new SimpleDateFormat("HH:mm").parse(time);
}
catch (ParseException e) {
e.printStackTrace();
}
long d = date.getTime();
java.sql.Date sqlDate = new java.sql.Date(d);
String sql3 = "CREATE TABLE IF NOT EXISTS DateTime"+
"(UniqueBusID VARCHAR(255) not NULL, " +
" Timenings DATETIME DEFAULT NULL ,"+
" PRIMARY KEY ( UniqueBusID ))";
stmt.executeUpdate(sql3);
stmt.executeUpdate("INSERT INTO DateTime " + "VALUES ('Test3','"+sqlDate.getTime()+"')");
EDIT
You have to use java.sql.Timestamp instead of java.sql.Date. As from javadoc,
"To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated."
So just replace the line
java.sql.Date sqlDate = new java.sql.Date(d);
with
java.sql.Timestamp sqlTime = new Timestamp(d);
You are doing it all right, except the pattern you have used to parse the String as Date i.e. HH:mm, which is wrong.
Correct Format : H:mm (H: 0-23; h:1-12)
try {
date = new SimpleDateFormat("H:mm").parse(time);
}
Here is the reference for Date and Time Patterns
I am surprised that it inserted '6828-00-00 00:00:00' :-)
Four problems here.
[1]
First that when you set a SimpleDateFormat, you're creating a java object Date. Java Date starts from Jan 1st 1970, so if you set only the hour and minute, the formatter will assume all other fields are zero (and not today), so
System.out.println(new SimpleDateFormat("HH:mm").parse("13:30")); // returns Thu Jan 01 13:30:00 BRT 1970
[2]
But then, you've called the getTime() method, which returns the millis since Jan 1st 1970
System.out.println(new SimpleDateFormat("HH:mm").parse("13:30").getTime()); //59400000
[3]
Then, you've tried to push this number into MySQL. MySQL datetime expects a string in the format
YYYY-MM-DD HH:MM:SS
(see https://dev.mysql.com/doc/refman/5.0/en/datetime.html)
Since MySQL is a very benevolent database ;-) it tries to convert 59400000 into this format, which obviously
mysql> insert into d values (59400000);
Query OK, 1 row affected (0.04 sec)
mysql> select * from d;
+---------------------+
| y |
+---------------------+
| 5940-00-00 00:00:00 |
+---------------------+
1 row in set (0.08 sec)
[4]
Of course, you could just adjust your SimpleDateFormat to MySQL expected date format, but you're concatenating strings in a INSERT query, and this is not a good idea for security reasons neither is efficient. Instead, you should use a PreparedStatement and set the Date object (not the millis)
What will be the regular expression for following Timestamp format
YYYY-MM-DD HH:mm:ss.S
YYYY-MM-DD HH:mm:ss.S AM/PM
YYYY-MM-DD HH:mm:ss.S AM/PM Z
YYYY-MM-DD HH:mm:ss.S Z
Where
Y: year,
M: Month,
D: Date,
H: hour,
m: minute,
s: second,
S: Milisecond 3 digit only,
Z: Time zone.
I am getting timestamp format in string format so want to validate it.
How to check above regular expression in GWT?
Just something simple as only describing the pattern like this:
^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}(?: [AP]M)?(?: [+-]\d{4})?$
as any tentative of real date validation with a regex sounds inherently wrong.
I got the uppercase Z as RFC822 timezone, regex needs changes to comply to TZDs or general textual time zones.
Apart from Datejs which relays on js to check a date-string, Gwt comes with DateTimeFormat to parse date-string and format dates with support for locales. It raises a IllegalArgumentException in the case the parsed string doesn't match the expected format .
String dateStr = "2011-04-21 20:37:36.999 -0800";
String fmt = "yyyy-MM-dd HH:mm:ss.S Z"; // your 4th case: YYYY-MM-DD HH:mm:ss.S Z
DateTimeFormat format = DateTimeFormat.getFormat(fmt);
try {
Date date = format.parse(dateStr);
System.out.println("Validated: " + date);
} catch (IllegalArgumentException e) {
System.out.println("Validation error: " + e.getMessage());
}
dateStr = "2011-04-21 08:37:36.999 PM -0800"; // your 3rd case YYYY-MM-DD HH:mm:ss.S AM/PM Z
fmt = "yyyy-MM-dd hh:mm:ss.S a Z";
format = DateTimeFormat.getFormat(fmt);
try {
Date date = format.parse(dateStr);
System.out.println("Validated: " + date);
} catch (IllegalArgumentException e) {
System.out.println("Validation error: " + e.getMessage());
}
You dont say whether the format string is fixed or it can be provided in runtime before performing the validation. So in the second case you need to use replace to change 'Y' by 'y', and 'AM/PM' to 'a' which are the symbols used in DateTimeFormat
I would say use Datejs
Otherwise you will need to do a lot of coding, and regex is not the best for verifying timestamps and if it is valid.
Datejs will check the date validity, and from that you will receive a Date object or null (if it is invalid!).
Date.parse("2013-02-02 12:01:01.000", "yyyy-MM-dd HH:mm:ss.u");
For more information see:
Datejs API documentation
Datejs Format spec
Looking for a bit of help with taking a dat from a DatePicker Widget and storing it in an sqlite database within the app. I have the following code:
java.util.Date utilDate = null;
String y = Integer.toString(date.getDayOfMonth()) + "/" + (date.getMonth()+1) + "/" + Integer.toString(date.getYear());
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyy");
utilDate = formatter.parse(y);
java.sql.Date z = new java.sql.Date(utilDate.getDate());
x = z.toString();
Log.v("The date: ", x);
}
Where date is the DatePicker widget. If I output the utilDate variable (i.e. the Java version of date) using logCat it seems to work fine and gives me a format like: Tue Jan 04 00:00:00 GMT 2011 which I am expecting but using the code above to get the sql version of the date, it always gives me the date 1970-01-01. I'm pretty sure the solution is very simple but I just can't see it.
This part: utilDate.getDate() is wrong.
Quote from Javadoc:
Returns the day of the month represented by this Date object. The value returned is between 1 and 31 representing the day of the month that contains or begins with the instant in time represented by this Date object, as interpreted in the local time zone.
So, you get a number between 1 and 31, and you expect a long that represents number of milliseconds that have passed since January 1, 1970 00:00:00.000 GMT.
Use
java.sql.Date z = new java.sql.Date(utilDate.getTime());
and everything should be OK.