How to parse 13-digit sqlite timestamp - android

The sqlite timestamp here is 13 digits, but how can one know its specific date. 1667458854391 should correspond to November 2022, but this year cannot be obtained regardless of interpretation or other conversions. I want to get time like 2022-11-03 15:00:54.
This method only works for ten digits
datetime('now','unixepoch', 'localtime')
This is sqllite timestamp, but product specific model does not know,only know that this timestamp is 13-digit just like these: 1667458854391 1667458752768
I tried to do this but it didn't feel compliant
datetime(substr(warehouse_inout_log.createTime,1,10),'unixepoch', 'localtime'),

The sqlite timestamp here is 13 digits, but how can one know its specific date.
You simply drop the 3 digits (the milliseconds) you do do this by dividing by 1000 or by using substring(createTime,1,10)
but this year cannot be obtained
If you want the year then you can use the strftime function with the %Y format String. e.g.
strftime('%Y',createTime/1000,'unixepoch','localtime')
I want to get time like 2022-11-03 15:00:54
What you have works. However it is simpler to use
datetime(createTime/1000,'unixepoch','localtime')
The following demonstrates the above (and also includes part of the official documentation regarding the formatting arguments):-
DROP TABLE IF EXISTS warehouse_inout_log;
CREATE TABLE IF NOT EXISTS warehouse_inout_log (createTime INTEGER);
INSERT INTO warehouse_inout_log VALUES
(1667458854391),(1667458752768),('1667458752768')
;
/*
The strftime() routine returns the date formatted according to the format string specified as the first argument. The format string supports the most common substitutions found in the strftime() function from the standard C library plus two new substitutions, %f and %J. The following is a complete list of valid strftime() substitutions:
%d day of month: 00
%f fractional seconds: SS.SSS
%H hour: 00-24
%j day of year: 001-366
%J Julian day number (fractional)
%m month: 01-12
%M minute: 00-59
%s seconds since 1970-01-01
%S seconds: 00-59
%w day of week 0-6 with Sunday==0
%W week of year: 00-53
%Y year: 0000-9999
%% %
*/
SELECT
strftime('%Y',createTime/1000,'unixepoch','localtime') AS createYear,
datetime(createTime/1000,'unixepoch','localtime') AS createDateTime,
strftime('%Y',substr(createTime,1,10),'unixepoch','localtime') AS createYearV2,
datetime(substr(createTime,1,10),'unixepoch','localtime') AS createDateTimeV2
FROM warehouse_inout_log
;
DROP TABLE IF EXISTS warehouse_inout_log;
Resulting in:-

Related

How to format Ints from datePicker to date-string

I am able to get the date values from date picker:
override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
Log.i("onDateSet", year.toString())
Log.i("onDateSet", month.toString())
Log.i("onDateSet", dayOfMonth.toString())
}
How can I format this ints into date-string, something like this for example: 2020-05-05
And I saw that the month always returning one month ago, if today is 5th month, it's returning 4th month.
Is it a bug or I just how it works and I need to add 1 to every month I'm getting from date picker?
The doc says that month int: the selected month (0-11 for compatibility with Calendar#MONTH), so yeah, this is the desired behavior and to format it to human readable you have to add 1 I suppose.
And for formatting a string you should probably manually concat the data you have
val date = "$year-${month+1}-$day"
(the quickest way to me, but you may choose some prettier one)
Alternatively you could do:
val date = LocalDate(year, monthOfYear + 1, dayOfMonth).toString("yyyy-MM-dd")
As mentioned in the AndroidSDK's Date class,
A month is represented by an integer from 0 to 11; 0 is January, 1 is February, and so forth; thus 11 is December.
An hour is represented by an integer from 0 to 23. Thus, the hour from midnight to 1 a.m. is hour 0, and the hour from noon to 1 p.m. is hour 12.
A minute is represented by an integer from 0 to 59 in the usual manner.
A second is represented by an integer from 0 to 61; the values 60 and 61 occur only for leap seconds.
Date and Year are represented in the usual manner, while the things mentioned above are represented with their respective rule.
Hence if its May, it will return 4, if its June it will return 5, and so on.
NOTE: Although this behavior may seem strange, it is consistent with the java.util.Calendar class (although it is not consistent with joda.time.DateTime).

Group By date in User's Timezone stored as Datetime format

I have stored date time values and I have values like this:
id | timestamp |
"6003" "2016-06-21 14:48:34"
"6002" "2016-06-21 17:18:34"
"6001" "2016-06-21 19:48:34"
"6000" "2016-06-21 22:18:34"
"5999" "2016-06-22 00:48:34"
"5998" "2016-06-22 03:18:34"
"5997" "2016-06-22 05:48:34"
"5996" "2016-06-22 08:18:34"
...
...
This all are stored in UTC (as I used CURRENT_TIMESTAMP to store value).
Now I want to count total no of records per day as per user's timezone and not GMT.
Like output should be
2016-06-21 20
2016-06-22 18
2016-06-23 17
2016-06-24 35
...
The count should calculated based on date in user's timezone.
How can I do that?
Okay, I got it. It wasn't too difficult.
Here is the query:
SELECT date(datetime(timestamp, 'localtime')), count(*) FROM log_time
GROUP BY date(datetime(timestamp, 'localtime'))

sqlite rounding 'error'

I'm using SQLite on and Android device.
I am attempting to convert a timestamp to a julian day, and round down the julian day by casting the result to an integer. For some reason, 2456902.0 is being rounded to 2456901. (I get the same result with the 'round' function as well)
I do need a workaround, but I would also like an explanation as to why this is happening if anyone has one.
My code and results are listed below:
cast(julianday((c.ts/1000), 'unixepoch') as int) as day,
julianday((c.ts/1000), 'unixepoch') as jd
When ts = 1409564846705, jd = 2456902.0, day = 2456901 (datetime is Mon Sep 01 04:47:26 CDT 2014)
When ts = 1409631153881, jd = 2456902.8, day = 2456902 (datetime is Mon Sep 01 23:12:33 CDT 2014)
I am trying to convert the timestamp to julian days to group records by day, but some data is falling into the wrong day (as you can see above, two records will be produced if I group by day, but the dates are part of the same day). I've resorted to: strftime('%d', datetime((c.ts/1000), 'unixepoch', 'localtime')) as day. The problem with this is that if I query for more than a month, there will be duplicate 'day of month's. Is there a better way to do this?
Julian day numbers have integer values at noon, so the start of a day is halfway between integers:
> SELECT julianday(1409631153881/1000, 'unixepoch', 'start of day');
2456902.5
It does not make sense to round Julian day numbers to integers unless you define precisely whether you want the previous or the next noon.
If you want just to group by the day, convert the value into a date string:
date(c.ts / 1000, 'unixepoch', 'localtime')
If you want a value that can be converted into a number, combine the year and the day of the year:
cast(strftime('%Y%j', c.ts / 1000, 'unixepoch', 'localtime') as int)
Alternatively, just divide the timestamp by the number of milliseconds in a day, but then you need to substract the proper offset of the timezone.

How can i get max data and minimum data from sqlite database in andorid?

In my project i stored the dates in the dateadded filed like below.
01-07-14 12:00
02-07-14 12:00
25-06-14 13.00
When i fire query for minimum date:
Select dateadded from dgadata order by dateadded asc limit 1
That is return 01-07-14 12:00 and even if i write Select min(dateadded) from dgadata the output is same. But here the minimum date is 26-06-14 13.00
And in the max date i write like
Select dateadded from dgadata order by dateadded desc limit 1
Here the result is 25-06-14 13.00 but here the max date is 02-07-14 12:00
I think my query is fine i don't know why i am getting wrong result.
SQLite doesn't have dedicated datetime types, but does have a few datetime functions. Follow the string representation formats (actually only formats 1-10) understood by those functions (storing the value as a string) and then you can use them, plus lexicographical comparison on the strings will match datetime comparison (as long as you don't try to compare dates to times or datetimes to times, which doesn't make a whole lot of sense anyway).
Depending on which language you use, you can even get automatic conversion. (Which doesn't apply to comparisons in SQL statements like the example, but will make your life easier.)
The reason is because the comparison is performed in the stored string. I think that this may help.
For what I can see, it seems that you have defined your dateadded field as TEXT, you should store a timestamp (integer) value instead of a text value, this way it will be easy to order them.
SQLite does not have a storage class set aside for storing dates and/or times. Instead,
the built-in Date And Time Functions of SQLite are capable of storing dates and times
as TEXT, REAL, or INTEGER values:
TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24,
4714 B.C. according to the proleptic Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can chose to store dates and times in any of these formats and freely
convert between formats using the built-in date and time functions.`
Another possible solution is to store your dates as YYYMMMDDHHMMSS, this way your order by will work aswell.

Simple date format giving the same date for two different strings

I have written a small method to return a date object when given a string. The method is as shown below:
public Date getDateObjectFromString(String dateAsString)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
Date tempDate = null;
try
{
tempDate = sdf.parse(dateAsString);
}
catch(ParseException pe)
{
//do some error reporting here
}
return tempDate;
}
Everything is working ok, but I've run into something that I'd like to clarify. When I pass two different strings to this method it is returning the same date when reading the value in the debugger. The two strings I am passing are:
2011-07-21T19:44:00.000-0400
2011-07-21T19:44:00.000-04:00
As you can see these two strings are nearly identical, and when I look at the variable output for these newly created dates in the debugger, it shows the exact same date/time for either string. So, does the colon in the second string (at 04:00) make any difference if the debugger is showing the same date? Should I worry or can I proceed without any weird bugs popping up later on?
This is what Wikipedia says about ISO 8601 'Time offsets from UTC'
The offset from UTC is given in the format ±[hh]:[mm], ±[hh][mm], or ±[hh].
So basically both formats you are using are permitted and you shouldn't worry about it.
The Android docs for SimpleDateFormat mention that they use RFC 822 timezones. When I went to the JavaDocs for SimpleDateFormat, which is what Android is attempting to mimic with this class, I see this note about RFC 822 timezones:
RFC 822 time zone: For formatting, the RFC 822 4-digit time zone
format is used:
RFC822TimeZone:
Sign TwoDigitHours Minutes
TwoDigitHours:
Digit Digit
TwoDigitHours must be between 00 and 23. Other definitions are as for
general time zones. For parsing, general time zones are also
accepted.
And here is the note for general time zones:
General time zone: Time zones are interpreted as text if they have
names. For time zones representing a GMT offset value, the following
syntax is used:
GMTOffsetTimeZone:
GMT Sign Hours : Minutes
Sign: one of ^^^
+ -
Hours:
Digit
Digit Digit
Minutes:
Digit Digit
Digit: one of
0 1 2 3 4 5 6 7 8 9
Hours must be between 0 and 23, and Minutes must be between 00 and 59.
The format is locale independent and digits must be taken from the
Basic Latin block of the Unicode standard.
In the definition for the general time zones, you will notice they use a ':'.
This means that your two strings, while different, will be parsed to the same time.
RFC 822 --> 2011-07-21T19:44:00.000-0400
General --> 2011-07-21T19:44:00.000-04:00
The colon in the second string doesn't make a difference; you can proceed without fear.

Categories

Resources