Java 8 LocalDateTime round to next X minutes - date

I want to convert Java 8 LocalDateTime to nearest 5 minutes. E.g.
1601 -> 1605
1602 -> 1605
1603 -> 1605
1604 -> 1605
1605 -> 1605
1606 -> 1610
1607 -> 1610
1608 -> 1610
1609 -> 1610
1610 -> 1610
I would like to use existing functionality of LocalDateTime or Math api. Any suggestions?

You can round towards the next multiple of five minutes using:
LocalDateTime dt = …
dt = dt.withSecond(0).withNano(0).plusMinutes((65-dt.getMinute())%5);
You can reproduce your example using
LocalDateTime dt=LocalDateTime.now().withHour(16).withSecond(0).withNano(0);
for(int i=1; i<=10; i++) {
dt=dt.withMinute(i);
System.out.printf("%02d%02d -> ", dt.getHour(), dt.getMinute());
// the rounding step:
dt=dt.plusMinutes((65-dt.getMinute())%5);
System.out.printf("%02d%02d%n", dt.getHour(), dt.getMinute());
}
→
1601 -> 1605
1602 -> 1605
1603 -> 1605
1604 -> 1605
1605 -> 1605
1606 -> 1610
1607 -> 1610
1608 -> 1610
1609 -> 1610
1610 -> 1610
(in this example, I clear the seconds and nanos only once as they stay zero).

Alternatively to what Holger suggests, you can create a TemporalAdjuster, which will allow you to write something like date.with(nextOrSameMinutes(5)):
public static void main(String[] args) {
for (int i = 0; i <= 10; i++) {
LocalDateTime d = LocalDateTime.of(LocalDate.now(), LocalTime.of(16, i, 0));
LocalDateTime nearest5 = d.with(nextOrSameMinutes(5));
System.out.println(d.toLocalTime() + " -> " + nearest5.toLocalTime());
}
}
public static TemporalAdjuster nextOrSameMinutes(int minutes) {
return temporal -> {
int minute = temporal.get(ChronoField.MINUTE_OF_HOUR);
int nearestMinute = (int) Math.ceil(1d * minute / minutes) * minutes;
int adjustBy = nearestMinute - minute;
return temporal.plus(adjustBy, ChronoUnit.MINUTES);
};
}
Note that this doesn't truncate the seconds/nanos from the original date. If you want that, you can amend the end of the adjuster to:
if (adjustBy == 0
&& (temporal.get(ChronoField.SECOND_OF_MINUTE) > 0 || temporal.get(ChronoField.NANO_OF_SECOND) > 0)) {
adjustBy += 5;
}
return temporal.plus(adjustBy, ChronoUnit.MINUTES)
.with(ChronoField.SECOND_OF_MINUTE, 0)
.with(ChronoField.NANO_OF_SECOND, 0);

Related

Caffeine eviction by size seems to not work

I am using caffeine cache.
I want to put it under size limitation but it does not work properly.
test 1:
Cache<String, String> cache = Caffeine.newBuilder()
.maximumSize(3)
.build();
Cache<String, String> cache = Caffeine.newBuilder()
.maximumSize(3)
.build();
for (int i = 1; i <= 10; i ++) {
String val = String.valueOf(i);
cache.put(val, val);
}
System.out.println("cache size: " + cache.estimatedSize() + ", cache keys: " + cache.asMap().values().stream().collect(Collectors.joining(",")));
result: cache size: 10, cache keys: 1,2,10
another test: trying to get key and set max to 1
Cache<String, String> cache = Caffeine.newBuilder()
.maximumSize(1)
.build();
for (int i = 1; i <= 10; i ++) {
String val = String.valueOf(i);
cache.put(val, val);
if (i % 2 == 0) {
cache.getIfPresent("5");
}
}
System.out.println("cache size: " + cache.estimatedSize() + ", cache keys: " + cache.asMap().values().stream().collect(Collectors.joining(",")));
cache size: 10, cache keys: 2,3,4,5,6,7,8,9,10
last test : run 100 times, max size 1
Cache<String, String> cache = Caffeine.newBuilder()
.maximumSize(1)
.build();
for (int i = 1; i <= 100; i ++) {
String val = String.valueOf(i);
cache.put(val, val);
if (i % 2 == 0) {
cache.getIfPresent("5");
}
}
System.out.println("cache size: " + cache.estimatedSize() + ", cache keys: " + cache.asMap().values().stream().collect(Collectors.joining(",")));
cache size: 99, cache keys: 96,97,99,19,23,58
can someone please help me understand this and how to make it work properly?
Thanks to Ben Manes, I added .executor(Runnable::run)
Now after doing this I do get only 3 items
Cache<String, String> cache = Caffeine.newBuilder()
.maximumSize(3)
.executor(Runnable::run)
.build();
for (int i = 1; i <= 10; i ++) {
String val = String.valueOf(i);
cache.put(val, val);
if (i % 2 == 0) {
cache.getIfPresent("5");
}
}
cache.cleanUp();
System.out.println("cache size: " + cache.estimatedSize() + ", cache: " + CodecUtils.toJson(cache.asMap().values()));
cache size: 3, cache: ["3","9","10"]
wouldn't this block my thread?
why isn't key 5 in the cache as I have been using it several times?
By default the cache will perform some operations asynchronously, such as eviction and notifying a removal listener. This is to minimize request latencies, as the auxiliary work is not necessary for the request itself and the user supplied callbacks might be expensive.
The cache's own maintenance work is very cheap, so you can safely run it on the caller's thread if desired by using Caffeine.executor(Runnable::run). This will penalize the caller with additionally evicting the entry, but will not block other operations from occurring. This is due to the cache internally using multiple locks and operation buffers, so that it can schedule work when a lock is busy rather than block threads.
In regards to the size, this is because the entry is evicted prior to being retrieved so it doesn't build up frequency. A getIfPresent doesn't increase the frequency if the entry is absent, whereas get(key, /* loading function */) would because it is penalized to load the value on the miss. The eviction policy utilizes both recency and frequency in its decisions, so it may evict recent arrivals early as often "one-hit wonders", aka cache pollution.
If we take your code as is and output the cache's state we see this,
for (int i = 1; i <= 10; i++) {
String val = String.valueOf(i);
cache.put(val, val);
System.out.println(val + " -> " + cache.asMap());
if (i % 2 == 0) {
cache.getIfPresent("5");
}
}
cache.cleanUp();
System.out.println("cache size: " + cache.estimatedSize());
1 -> {1=1}
2 -> {1=1, 2=2}
3 -> {1=1, 2=2, 3=3}
4 -> {2=2, 3=3, 4=4}
5 -> {2=2, 3=3, 5=5}
6 -> {2=2, 3=3, 6=6}
7 -> {2=2, 3=3, 7=7}
8 -> {2=2, 3=3, 8=8}
9 -> {2=2, 3=3, 9=9}
10 -> {2=2, 3=3, 10=10}
cache size: 3
If we access key 5 on every iteration then it is retained,
for (int i = 1; i <= 10; i++) {
String val = String.valueOf(i);
cache.put(val, val);
System.out.println(val + " -> " + cache.asMap());
cache.getIfPresent("5");
}
cache.cleanUp();
System.out.println("cache size: " + cache.estimatedSize());
1 -> {1=1}
2 -> {1=1, 2=2}
3 -> {1=1, 2=2, 3=3}
4 -> {2=2, 3=3, 4=4}
5 -> {2=2, 3=3, 5=5}
6 -> {3=3, 5=5, 6=6}
7 -> {3=3, 5=5, 7=7}
8 -> {3=3, 5=5, 8=8}
9 -> {3=3, 5=5, 9=9}
10 -> {3=3, 5=5, 10=10}
cache size: 3

Flutter float number rounding

I want to achieve the following in my code, and can't seem to find a proper solution:
I need code that will always show 6 digits of a number, no matter being int greater than 999999 or floating point smaller than 0.
100000 -> 100000
1000000 -> 100000
10000.0 -> 10000
100.01111 -> 100.011
0.000001 -> 0
0.000011 -> 0.00001
With some help in the comments, I got a solution that works for me. If someone has more elegant way of doing this please do share it.
int desiredPrecision = 6;
int numberOfDigitsOnTheLeft = val.toInt().toString().length;
String sixDigitString = val.toStringAsFixed(desiredPrecision-numberOfDigitsOnTheLeft);
as an option
void main() {
print(_normalizeNum(10000.0));
print(_normalizeNum(100000));
print(_normalizeNum(1000000));
print(_normalizeNum(10000.0));
print(_normalizeNum(100.01111));
print(_normalizeNum(0.000001));
print(_normalizeNum(0.000011));
}
String _normalizeNum(num d) {
d = d.clamp(double.negativeInfinity, 999999);
d = num.parse(d.toStringAsFixed(6).substring(0, 7));
if (d == d.toInt()) {
d = d.toInt();
}
return d.toString();
}

Recursive function in XCode Playground (Swift)

I'm learning recursive functions in Swift, and I did the following:
func recursive(i: Int) -> Int {
if i == 1 {
return 1
} else if i >= 2 {
return recursive(i: i - 1) + 1
}
return 0
}
I couldn't figure out why the function above is not working. I've tested it by doing the below doing print(recursive(10)), which gives me an output of 10. I expected the output to be 1. Can anyone help me with this? Thank you in advance.
I'm using Playgrounds on XCode 8.3.
When you do this:
recursive(i: i - 1) + 1
… then you are in effect decrementing i and then incrementing it again. That cancels out and you arrive at i again.
Let's write down what calculation would be done for i = 3:
(3 - 1) + 1 = ((2 - 1) + 1) + 1 = (((1) + 1) + 1) = 3
This is a perfect example of printing numbers without using any loop.
The recursive functions are very useful to handle such cases.
func printCount( count : inout Int , limit : Int) {
print(count, terminator: " ")
count += 1
if count > limit {
return
}
printCount(count: &count , limit: limit)
}
var count = 11
let limit = 20
printCount(count: &count , limit: limit)
Output : 11 12 13 14 15 16 17 18 19 20

how to get complete startup time on solaris

I'm struggling to find a command or even a way to find the complete startup time on my Solaris(sun4u sparc SUNW,Netra-T12) box
Solaris
who -b gives me Jun 22 11:09 but no year
same with last reboot | head -n 1
However in my Linux(GNU/Linux x86_64) boxes i'm able to get the full startup time
Linux
who -b gives me 2014-08-23 11:09
Any help?
EDIT
output of apptrace uptime 2>&1
-> uptime -> libc.so.1:int atexit(int (*)() = 0xff3c59ec)
<- uptime -> libc.so.1:atexit()
-> uptime -> libc.so.1:int atexit(int (*)() = 0x10ae8)
<- uptime -> libc.so.1:atexit()
-> uptime -> libc.so.1:char * setlocale(int = 0x6, const char * = 0x10af8 "")
<- uptime -> libc.so.1:setlocale() = 0xfefdb25e
-> uptime -> libc.so.1:char * textdomain(const char * = 0x10afc "SUNW_OST_OSCMD")
<- uptime -> libc.so.1:textdomain() = 0x22b58
-> uptime -> libc.so.1:sysinfo(0x202, 0xffbff97f, 0x1) ** NR
-> uptime -> libc.so.1:void * malloc(size_t = 0x73)
<- uptime -> libc.so.1:malloc() = 0x23158
-> uptime -> libc.so.1:sysinfo(0x202, 0x23158, 0x73) ** NR
-> uptime -> libc.so.1:const char * getexecname(void)
<- uptime -> libc.so.1:getexecname() = 0xffbfffc5
-> uptime -> libc.so.1:strlen(0xffbfffc5, 0x23158, 0x10800) ** NR
-> uptime -> libc.so.1:void * malloc(size_t = 0x82)
<- uptime -> libc.so.1:malloc() = 0x231d8
-> uptime -> libc.so.1:strcpy(0x231d8, 0xffbfffc5, 0xffbfffd4) ** NR
-> uptime -> libc.so.1:char * strrchr(const char * = 0x231d8 "/usr/bin/uptime", int = 0x2f)
<- uptime -> libc.so.1:strrchr() = 0x231e0
-> uptime -> libc.so.1:strlen(0x231d8, 0x2f, 0x231eb) ** NR
-> uptime -> libc.so.1:char * strtok(char * = 0x23158 "sparcv9+vis2 sparcv9+vis sparcv9 sparcv8plus+vis2 sparcv8plus+vis sparcv8plus sparcv8 sparcv8-fsmuld sparcv7 sparc", const char * = 0x10b60 " ")
<- uptime -> libc.so.1:strtok() = 0x23158
-> uptime -> libc.so.1:strcpy(0x231e1, 0x23158, 0x231e1) ** NR
-> uptime -> libc.so.1:char * strcat(char * = 0x231e1 "sparcv9+vis2", const char * = 0x10b64 "/")
<- uptime -> libc.so.1:strcat() = 0x231e1
-> uptime -> libc.so.1:char * strcat(char * = 0x231e1 "sparcv9+vis2/", const char * = 0xffbfffce "uptime")
<- uptime -> libc.so.1:strcat() = 0x231e1
-> uptime -> libc.so.1:access(0x231d8, 0x1, 0x231f1) ** NR
-> uptime -> libc.so.1:char * strtok(char * = 0x0 <NULL>, const char * = 0x10b84 " ")
<- uptime -> libc.so.1:strtok() = 0x23165
-> uptime -> libc.so.1:strcpy(0x231e1, 0x23165, 0x231f1) ** NR
-> uptime -> libc.so.1:char * strcat(char * = 0x231e1 "sparcv9+vis", const char * = 0x10b64 "/")
<- uptime -> libc.so.1:strcat() = 0x231e1
-> uptime -> libc.so.1:char * strcat(char * = 0x231e1 "sparcv9+vis/", const char * = 0xffbfffce "uptime")
<- uptime -> libc.so.1:strcat() = 0x231e1
-> uptime -> libc.so.1:access(0x231d8, 0x1, 0x231f0) ** NR
-> uptime -> libc.so.1:char * strtok(char * = 0x0 <NULL>, const char * = 0x10b84 " ")
<- uptime -> libc.so.1:strtok() = 0x23171
-> uptime -> libc.so.1:strcpy(0x231e1, 0x23171, 0x231f0) ** NR
-> uptime -> libc.so.1:char * strcat(char * = 0x231e1 "sparcv9", const char * = 0x10b64 "/")
<- uptime -> libc.so.1:strcat() = 0x231e1
-> uptime -> libc.so.1:char * strcat(char * = 0x231e1 "sparcv9/", const char * = 0xffbfffce "uptime")
<- uptime -> libc.so.1:strcat() = 0x231e1
-> uptime -> libc.so.1:access(0x231d8, 0x1, 0x231ec) ** NR
-> uptime -> libc.so.1:execve(0x231d8, 0xffbff9e4, 0xffbff9ec) ** NR
ld.so.1: uptime: warning: /usr/lib/abi/sparcv9/apptrace.so.1: open failed: illegal insecure pathname
ld.so.1: uptime: warning: /usr/lib/abi/sparcv9/apptrace.so.1: audit initialization failure: disabled
3:26pm up 270 day(s), 13:42, 2 users, load average: 2.08, 2.07, 2.07
Here is a hackish way to get the boot time on Solaris 10 under ksh or bash:
perl -le "print scalar localtime hex(\"$(apptrace -v getutxent uptime 2>&1 | nawk '
/ut_type:/ {if($3=="0x2"){boot=1}}
boot == 1 && $0 ~ ".*tv_sec:.*" {sub("0x","",$3);print $3;exit}')\")"
Note that you need to be root to run it on Solaris 10 but not on Solaris 11.
Edit:
Here is a much simpler way that doesn't requires root privileges:
perl -le "print scalar localtime $(kstat -pn system_misc -s boot_time|cut -f 2)"

Convert timestamp to datetime in erlang

How can I convert a timestamp (number of milliseconds since 1 Jan 1970..., aka epoch) to Date or DateTime format in Erlang? Something like {Year,Month,Day}.
Roughly:
msToDate(Milliseconds) ->
BaseDate = calendar:datetime_to_gregorian_seconds({{1970,1,1},{0,0,0}}),
Seconds = BaseDate + (Milliseconds div 1000),
{ Date,_Time} = calendar:gregorian_seconds_to_datetime(Seconds),
Date.
It just so happens that I have a github gist with a bunch of datetime utilities for exactly this purpose: http://gist.github.com/104903. Calendar has most of the low level plumbing for this stuff.
-module(date_util).
-compile(export_all).
epoch() ->
now_to_seconds(now())
.
epoch_hires() ->
now_to_seconds_hires(now())
.
now_to_seconds({Mega, Sec, _}) ->
(Mega * 1000000) + Sec
.
now_to_milliseconds({Mega, Sec, Micro}) ->
now_to_seconds({Mega, Sec, Micro}) * 1000
.
now_to_seconds_hires({Mega, Sec, Micro}) ->
now_to_seconds({Mega, Sec, Micro}) + (Micro / 1000000)
.
now_to_milliseconds_hires({Mega, Sec, Micro}) ->
now_to_seconds_hires({Mega, Sec, Micro}) * 1000
.
epoch_gregorian_seconds() ->
calendar:datetime_to_gregorian_seconds({{1970,1,1}, {0,0,0}})
.
now_to_gregorian_seconds() ->
epoch_to_gregorian_seconds(now())
.
epoch_to_gregorian_seconds({Mega, Sec, Micro}) ->
epoch_to_gregorian_seconds(now_to_seconds({Mega, Sec, Micro}));
epoch_to_gregorian_seconds(Now) ->
EpochSecs = epoch_gregorian_seconds()
, Now + EpochSecs
.
gregorian_seconds_to_epoch(Secs) ->
EpochSecs = epoch_gregorian_seconds()
, Secs - EpochSecs
.
date_to_epoch(Date) ->
datetime_to_epoch({Date, {0,0,0} })
.
datetime_to_epoch({Date, Time}) ->
gregorian_seconds_to_epoch(
calendar:datetime_to_gregorian_seconds({Date, Time}))
.
is_older_by(T1, T2, {days, N}) ->
N1 = day_difference(T1, T2)
, case N1 of
N2 when (-N < N2) ->
true;
_ ->
false
end
.
is_sooner_by(T1, T2, {days, N}) ->
case day_difference(T1, T2) of
N1 when N > N1 ->
true;
_ ->
false
end
.
is_time_older_than({Date, Time}, Mark) ->
is_time_older_than(calendar:datetime_to_gregorian_seconds({Date, Time})
, Mark);
is_time_older_than(Time, {DateMark, TimeMark}) ->
is_time_older_than(Time
, calendar:datetime_to_gregorian_seconds({DateMark, TimeMark}));
is_time_older_than(Time, Mark) when is_integer(Time), is_integer(Mark) ->
Time < Mark
.
day_difference({D1, _}, D2) ->
day_difference(D1, D2);
day_difference(D1, {D2, _}) ->
day_difference(D1, D2);
day_difference(D1, D2) ->
Days1 = calendar:date_to_gregorian_days(D1)
, Days2 = calendar:date_to_gregorian_days(D2)
, Days1 - Days2
.
is_time_sooner_than({Date, Time}, Mark) ->
is_time_sooner_than(calendar:datetime_to_gregorian_seconds({Date, Time})
, Mark);
is_time_sooner_than(Time, {DateMark, TimeMark}) ->
is_time_sooner_than(Time
, calendar:datetime_to_gregorian_seconds({DateMark, TimeMark}));
is_time_sooner_than(Time, Mark) when is_integer(Time), is_integer(Mark) ->
Time > Mark
.
subtract(Date, {days, N}) ->
New = calendar:date_to_gregorian_days(Date) - N
, calendar:gregorian_days_to_date(New)
.
add(Date, {days, N}) ->
New = calendar:date_to_gregorian_days(Date) + N
, calendar:gregorian_days_to_date(New)
.
OTP 21.0 added this function
calendar:system_time_to_universal_time(Time, TimeUnit) -> datetime()
Types
Time = integer()
TimeUnit = erlang:time_unit()
Converts a specified system time into universal date and time.
Example:
> os:system_time(1000).
1598512151718
> calendar:system_time_to_universal_time(1598512151718, 1000).
{{2020,8,27},{7,9,11}}
Refrence: https://erlang.org/doc/man/calendar.html#system_time_to_universal_time-2