i am trying to set the modification times on a fil...
# kotlin-native
n
i am trying to set the modification times on a file apparently in win32 api there exists
dwHighDateTime
and
dwLowDateTime
which are there so that a 64 bit value can be split into the lower and upper 32 bit how would i split a kotlin Long into 2 UInt (DWORD) values ? or can i just write a Long value to the
FILETIME
struct via some unsafe operation ?
d
Should be doable with some bit shifting
n
Unfortunately bit shifting is unpleasant in Kotlin compared to other languages like Java, C, and Python.
n
it was doable.. the more annoying thing it turns out that windows uses units of 100 nanoseconds since 1.1.1601 and apparently overflowing that value in kotlinx-datetime leads to subtracting time.. (took me a while to spot that)
j
Why is it more unpleasant than C or Java? 🤔
n
because we do not have
>>
<<
&
&=
|
|=
^
^=
, etc and have to use calls like
a.shr(b)
or
a = a or b
instead it makes converting code that uses these operators complicated and nested in brackets and functions have a different order of evaluation than operators do.. so you need to keep that in mind as well
n
Also the use of infix functions instead of proper operators makes bit shifting code more difficult to read/understand.
i
apparently overflowing that value in kotlinx-datetime leads to subtracting time..
@Nikky Could you provide more details on that? What operation has overflown?
n
i am using kotlinx-datetime to convert between unixEpochMilliseconds and windows.. whatever they call it
Copy code
val windowsEpoch = LocalDateTime(1601, Month.JANUARY, 1, 0, 0).toInstant(TimeZone.UTC)
val lastModifiedInstant = Instant.fromEpochMilliseconds(meta.lastModifiedAtMillis!!)
val lastModifiedAt = (lastModifiedInstant - windowsEpoch).inWholeNanoseconds / 100L
this somehow results in a date around year
1404
(so about 600 years off) this works though
Copy code
val lastModifiedAt = (lastModifiedInstant - windowsEpoch).inWholeMicroseconds * 10L
my best guess is that somewhere it goes past max long when i get the time in nanoseconds, but its fine with microseconds
i
Yes,
inWholeNanoseconds
can represent duration range of about +-292 years. However for a greater duration, the value of
inWholeNanoseconds
doesn't overflow to negative but rather saturates at the maximum value, i.e. at 2^31-1 nanoseconds.
The variant with
inWholeMicroseconds
is ok, if you're fine with loosing some precision, because such big Duration values can only represent values accurate to milliseconds. If you want to get the maximum precision, you can use
instantNow.minus(instantEpoch, DateTimeUnit.TimeBased)
or
instantEpoch.until(instantNow, DateTimeUnit.TimeBased)
functions, and pass there
DateTimeUnit.NANOSECOND * 100
as a date time unit to get the difference between these two instants expressed in 100ns intervals, which I suppose is what you need.
n
it works from all i see, seems like that bit of precision is not critical.. or the clock is not that precise anyways but i will try that out as well
i
I see now that your input value
meta.lastModifiedAtMillis
is in milliseconds too, so it should be fine to use
Duration
to store even that big difference values at millisecond precision and then convert them to 100ns-interval values.