Dart: DateTime.parse() not including microseconds - dart

See the following code:
void main()
{
String test = '2017-10-11T12:03:46.351363-04:00';
DateTime testDate = DateTime.parse(test);
print(testDate.microsecond);
print(testDate.toString());
}
When running this code I lose the microseconds in the string that I parse. Why is this and is there anyway to solve this?
The Dart docs say that the parse method supports microseconds.

'2017-10-11T12:03:46.351363-04:00' is not a format Dart's DateTime can handle.
DateTime only supports Z for GMT or no Z for local time.
Just print the value from a created DateTime to see what format it can parse.
print(DateTime.now());
print(DateTime.now().toUtc())
DateTime has also 2 constructors fromMicrosecondsSinceEpoch and fromMillisecondsSinceEpoch to create an instance from an integer value.

There's an issue here
https://github.com/dart-lang/co19/issues/17
As the test show it only 6 decimal places
https://github.com/dart-lang/co19/commit/8465825f60c9580d82ae01ffc040f3b589aaf667#diff-02c526d1dcb5aa2dcdab3500c14ede87R40
You can parse format 2018-12-11T12:00:32.304272Z
but cannot parse 2018-12-11T12:00:32.304272001Z

I found an issue for dart-lang/sdk.
https://github.com/dart-lang/sdk/issues/44876
The web Date object doesn't support microseconds. It's implemented
using the JavaScript Date object which only supports millisecond
precision. So, working as well as possible.

Related

How I can hide some x axis labels in seaborn time-series plot? [duplicate]

How can I convert a DataFrame column of strings (in dd/mm/yyyy format) to datetime dtype?
The easiest way is to use to_datetime:
df['col'] = pd.to_datetime(df['col'])
It also offers a dayfirst argument for European times (but beware this isn't strict).
Here it is in action:
In [11]: pd.to_datetime(pd.Series(['05/23/2005']))
Out[11]:
0 2005-05-23 00:00:00
dtype: datetime64[ns]
You can pass a specific format:
In [12]: pd.to_datetime(pd.Series(['05/23/2005']), format="%m/%d/%Y")
Out[12]:
0 2005-05-23
dtype: datetime64[ns]
If your date column is a string of the format '2017-01-01'
you can use pandas astype to convert it to datetime.
df['date'] = df['date'].astype('datetime64[ns]')
or use datetime64[D] if you want Day precision and not nanoseconds
print(type(df_launath['date'].iloc[0]))
yields
<class 'pandas._libs.tslib.Timestamp'>
the same as when you use pandas.to_datetime
You can try it with other formats then '%Y-%m-%d' but at least this works.
You can use the following if you want to specify tricky formats:
df['date_col'] = pd.to_datetime(df['date_col'], format='%d/%m/%Y')
More details on format here:
Python 2 https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior
Python 3 https://docs.python.org/3.7/library/datetime.html#strftime-strptime-behavior
If you have a mixture of formats in your date, don't forget to set infer_datetime_format=True to make life easier.
df['date'] = pd.to_datetime(df['date'], infer_datetime_format=True)
Source: pd.to_datetime
or if you want a customized approach:
def autoconvert_datetime(value):
formats = ['%m/%d/%Y', '%m-%d-%y'] # formats to try
result_format = '%d-%m-%Y' # output format
for dt_format in formats:
try:
dt_obj = datetime.strptime(value, dt_format)
return dt_obj.strftime(result_format)
except Exception as e: # throws exception when format doesn't match
pass
return value # let it be if it doesn't match
df['date'] = df['date'].apply(autoconvert_datetime)
Try this solution:
Change '2022–12–31 00:00:00' to '2022–12–31 00:00:01'
Then run this code: pandas.to_datetime(pandas.Series(['2022–12–31 00:00:01']))
Output: 2022–12–31 00:00:01
Multiple datetime columns
If you want to convert multiple string columns to datetime, then using apply() would be useful.
df[['date1', 'date2']] = df[['date1', 'date2']].apply(pd.to_datetime)
You can pass parameters to to_datetime as kwargs.
df[['start_date', 'end_date']] = df[['start_date', 'end_date']].apply(pd.to_datetime, format="%m/%d/%Y")
Use format= to speed up
If the column contains a time component and you know the format of the datetime/time, then passing the format explicitly would significantly speed up the conversion. There's barely any difference if the column is only date, though. In my project, for a column with 5 millions rows, the difference was huge: ~2.5 min vs 6s.
It turns out explicitly specifying the format is about 25x faster. The following runtime plot shows that there's a huge gap in performance depending on whether you passed format or not.
The code used to produce the plot:
import perfplot
import random
mdYHM = range(1, 13), range(1, 29), range(2000, 2024), range(24), range(60)
perfplot.show(
kernels=[lambda x: pd.to_datetime(x), lambda x: pd.to_datetime(x, format='%m/%d/%Y %H:%M')],
labels=['pd.to_datetime(x)', "pd.to_datetime(x, format='%m/%d/%Y %H:%M')"],
n_range=[2**k for k in range(19)],
setup=lambda n: pd.Series([f"{m}/{d}/{Y} {H}:{M}"
for m,d,Y,H,M in zip(*[random.choices(e, k=n) for e in mdYHM])]),
equality_check=pd.Series.equals,
xlabel='len(df)'
)

Datetime and iso format

sometimes toString(datetime()) return the milliseconds without the leading zeros to reach the length of 3 (yyyy-MM-dd'T'HH:mm:ss.SSSXXX). Is it a bug or normal behavior?
For example:
2019-11-21T15:59:22.53Z -> it should be 2019-11-21T15:59:22.053Z
2019-11-21T15:59:21.216Z -> OK
2019-11-21T15:30:09.042Z -> OK
This behavior causes an issue when I try to convert the string into a date.
Thank you
Try using the apoc.temporal.format function, specifying the iso_instant type conversion.
For example:
RETURN apoc.temporal.format(datetime("2019-11-21T22:04:19.13Z"), 'iso_instant');
will return:
"2019-11-21T22:04:19.130Z"
[UPDATE]
Since the TOSTRING() function is not documented to return any particular ISO 8601 string format for a datetime, one should not depend on it returning a specific format -- or even returning the same string for the same datetime across versions.
However, if you want a non-APOC approach that works with recent versions of neo4j (like, 3.5.12, on which this was tested), here is an example of one way to modify the current TOSTRING() output string to always have a 3-digit millisecond value:
// Generate a string.
// You can play with the number of digits after ".", and
// even eliminate the "." and any following digits.
WITH TOSTRING(datetime("2019-11-21T22:04:10.1Z")) AS d
// Always return a 3-digit millisecond time in result
WITH d, LENGTH(d) AS lth
RETURN d, CASE WHEN lth < 24
THEN SUBSTRING(d, 0, lth-1) + SUBSTRING('.000Z', lth - 20)
ELSE d END AS result

Trouble subtracting time from a moment

I am working on a project that uses a different timezone than the one I currently live in:
moment.tz.add("Asia/Seoul|LMT KST JST KST KDT KDT|-8r.Q -8u -90 -90 -9u -a0|0123141414141414135353|-2um8r.Q 97XV.Q 1m1zu kKo0 2I0u OL0 1FB0 Rb0 1qN0 TX0 1tB0 TX0 1tB0 TX0 1tB0 TX0 2ap0 12FBu 11A0 1o00 11A0|23e6")
Then formatted it as such:
const kST = moment().tz('Asia/Seoul').format("HH:mm");
Now I want to be able to subtract a year from that. Looking at examples of how to do that I found something like var foo = moment(blah, "HH:mm).subtract(1, "years")
I assumed that since I already defined the moment with the 'const kST' I could simply substitute "kST" for "moment" as such:
const firstTimeConverted = kST(firstBus, "HH:mm").subtract(1, "years");
Unfortunately that doesn't work. Any thoughts how I might do this would be much appreciated.
In your code, kST isn't a function - it's a string. The format returns a string formatted as specified.
You probably want:
const firstTimeConverted = moment.tz(firstBus, "HH:mm", `Asia/Seoul`).subtract(1, "years");
This will parse the string in your firstBus variable in HH:mm format (such as "23:45"), and interpret as belonging to the Asia/Seoul time zone on the current date there. Then it will subtract a year and return the result as a moment object. If you want a string, you would then need to call the format function.

Why is the gettimeofday timezone wrong?

Both ftime and gettimeofday are returning 0 for the current timezone in Ubuntu 16. The timezone is set correctly in the date and time settings provided by Ubuntu. There is no TZ env variable set.
I don't want to just "fix" it because this is production software used in many different contexts. So I just want a reliable way of programmatically getting the timezone (and preferably the current DST offset as well).
My attempts so far:
#if 0
timeb tbTime;
ftime(&tbTime);
int CurTz = -tbTime.timezone;
#else
struct timeval tv;
struct timezone tz;
int r = gettimeofday(&tv, &tz);
if (r)
return NO_ZONE;
int CurTz = tz.tz_minuteswest;
#endif
The 'date' command is working:
matthew#mallen-ubuntu:~$ date +%Z
AEDT
matthew#mallen-ubuntu:~$ date +%z
+1100
I could just spawn a process to call "date", but that seems very heavy handed when some API calls are available.
On GNU/Linux, the second argument of gettimeofday is quite useless and should always be NULL. The manual page for gettimeofday says this:
The use of the timezone structure is obsolete; the tz argument should normally be specified as NULL.
Even on non-Linux systems, the tz_dsttime has useless semantics (e.g., it reports that India uses DST because it did so for a brief period about seventy years ago).
If you need to obtain the time zone for the current time, you need to use localtime or localtime_r and examine the broken-down time structure it produces (and not global variables such as daylight). The struct tm members you are probably interested are tm_isdst, tm_gmtoff, and perhaps tm_zone. The latter two are glibc extensions.

Timestamp (milliseconds) in Swift

I am receiving a creation date for an object in a database as milliseconds (# of milliseconds since epoch or whatever) and would like to convert it to/from a string in Swift!
I think I'd need a data type of CUnsignedLong?
I am trying something like this but it outputs the wrong number:
var trial: CUnsignedLong = 1397016000000
println(trial) //outputs 1151628800 instead!
I'm guess this is the wrong data type so what would you all advise in a situation like this?
In Java I was using long which worked.
Thanks!
func currentTimeMillis() -> Int64{
let nowDouble = NSDate().timeIntervalSince1970
return Int64(nowDouble*1000)
}
Working fine
On 32-bit platforms, CUnsignedLong is a 32-bit integer, which is not large
enough to hold the number 1397016000000. (This is different from Java, where
long is generally a 64-bit integer.)
You can use UInt64 or NSTimeInterval (a type alias for Double), which is what the
NSDate methods use.

Resources