How to represent clock - datetime

Is there a built in way to represent clock in dart or flutter? I only want to represent time in 24 hours clock.
P.S. I am currently rolling my own solution because I needed a static, locale insensitive clock which is pretty easy. But I was just looking if there is a way.
P.P.S I owned the backend. So I was able to tweak it to return date.
Old question: I am getting a time back from an API which I want to parse in my flutter app. I had a look at DateTime class but there is no apparent method to parse time as I am not interested in the date. Is there a way to represent only time and parse it in dart? Ex- 20:05:00 which should mean 5 minutes past 8 o'clock.
P.S This is my implementation
extension NumberUtil on int {
bool isBetween(int lowerBound, int upperBound) {
/// Checks if an int is between lower and upper bound both inclusive
return this >= lowerBound && this <= upperBound;
}
}
class Time {
final int hours, minutes, seconds;
Time(this.hours, this.minutes, this.seconds) {
assert( hours.isBetween(0, 24) && minutes.isBetween(0, 60) && seconds.isBetween(0, 60) );
}
factory Time.parse(String string) {
/// String should be in 24 hour format: hh:mm:ss. The caller is responsible
/// for catching the parsing exception because:
/// 1. It should almost never occur.
/// 2. Because this is a UI app, the UI is most suited to handle that by
/// displaying a "something went wrong" dialog
final temp = string.split(':');
assert (temp.length == 3);
return Time(
int.parse(temp[0]),
int.parse(temp[1]),
int.parse(temp[2]),
);
}
int compareTo(Time t) {
/// Performs a 3 way comparison between the this and t. Returns 0 if the two
/// objects are same. Returns 1 if this is greater than t. Returns -1 otherwise
if (this.hours > t.hours) return 1;
if (this.hours < t.hours) return -1;
/// at this point hours is same
if (this.minutes > t.minutes) return 1;
if (this.minutes < t.minutes) return -1;
/// At this point minutes are same
if (this.seconds > t.seconds) return 1;
if (this.seconds < t.seconds) return -1;
/// At this point everything is same
return 0;
}
}

Do you mean this?
currentTime = DateTime.now();
targetTime = DateTime.parse('here some times format');
currentTime.difference(targetTime) or currentTime.difference(targetTime).inHours // this??
or
Do you find this package
https://pub.dev/packages/timeago

Related

Database DateTime milli and nano seconds are truncated by default if they are 0s, while using it in Java 11 using ZonedDateTime

I am fetching datetime from an Oracle database and parsing in Java 11 using ZonedDateTime as below:
Oracle --> 1/19/2020 06:09:46.038631 PM
Java ZonedDateTime output --> 2020-01-19T18:09:46.038631Z[UTC]
Oracle --> 1/19/2011 4:00:00.000000 AM
Java ZonedDateTime output --> 2011-01-19T04:00Z[UTC] (So, here the 0s are truncated by default.
However, my requirement is to have consistent fixed length output like #1.)
Expected Java ZonedDateTime output --> 2011-01-19T04:00:00.000000Z[UTC]
However, I didn’t find any date API methods to achieve above expected output. Instead of manipulating a string, is there a way to preserve the trailing 0s with fixed length?
We have consistent ZonedDateTime types in the application, so we do not prefer to change that.
We have consistent ZonedDateTime type in application, so we do not
prefer to change that.
Why do you think 2011-01-19T04:00Z[UTC] is inconsistent? A date-time object is supposed to hold (and provide methods/functions to operate with) only the date, time, and time-zone information. It is not supposed to store any formatting information; otherwise, it will violate the Single-responsibility principle. The formatting should be handled by a formating class e.g. DateTimeFormatter (for modern date-time API), DateFormat (for legacy java.util date-time API) etc.
Every class is supposed to override the toString() function; otherwise, Object#toString will be returned when its object will be printed. A ZonedDateTime has date, time and time-zone information. Given below is how its toString() for time-part has been implemented:
#Override
public String toString() {
StringBuilder buf = new StringBuilder(18);
int hourValue = hour;
int minuteValue = minute;
int secondValue = second;
int nanoValue = nano;
buf.append(hourValue < 10 ? "0" : "").append(hourValue)
.append(minuteValue < 10 ? ":0" : ":").append(minuteValue);
if (secondValue > 0 || nanoValue > 0) {
buf.append(secondValue < 10 ? ":0" : ":").append(secondValue);
if (nanoValue > 0) {
buf.append('.');
if (nanoValue % 1000_000 == 0) {
buf.append(Integer.toString((nanoValue / 1000_000) + 1000).substring(1));
} else if (nanoValue % 1000 == 0) {
buf.append(Integer.toString((nanoValue / 1000) + 1000_000).substring(1));
} else {
buf.append(Integer.toString((nanoValue) + 1000_000_000).substring(1));
}
}
}
return buf.toString();
}
As you can see, the second and nano parts are included in the returned string only when they are greater than 0. It means that you need to use a formatting class if you want these (second and nano) zeros in the output string. Given below is an example:
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String input = "1/19/2011 4:00:00.000000 AM";
// Formatter for input string
DateTimeFormatter inputFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("M/d/u H:m:s.n a")
.toFormatter(Locale.ENGLISH);
ZonedDateTime zdt = LocalDateTime.parse(input, inputFormatter).atZone(ZoneOffset.UTC);
// Print `zdt` in default format i.e. the string returned by `zdt.toString()`
System.out.println(zdt);
// Formatter for input string
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.nnnnnnz");
String output = zdt.format(outputFormatter);
System.out.println(output);
}
}
Output:
2011-01-19T04:00Z
2011-01-19T04:00:00.000000Z
Food for thought:
public class Main {
public static void main(String[] args) {
double d = 5.0000;
System.out.println(d);
}
}
What output do you expect from the code given above? Does 5.0 represent a value different from 5.0000? How will you print 5.0000? [Hint: Check String#format, NumberFormat, BigDecimal etc.]

Coin Change Dynamic Programming

QUESTION:
I'm having trouble finding the minimum amount of coins needed to reach a specific sum. I'm pretty sure this is done easiest recursively and using the dynamic programming methodology, I should basically get Math.min("takeACoin","leaveACoin");
Unfortunately, My code doesn't terminate though I do have if statements that terminate under the condition that the sum is met, the array of coins is depleted, or if the sum is over. Please look at my code below and let me know what I'm doing wrong and especially why my code continues executing until it receives a stackoverflow error though I have the appropriate terminating conditions.
CODE:
private static final int S = 3;
public static int arr[] = {1,2};
public static void main(String[] args) {
Interview i = new Interview();
i.sumCoins(arr, 0);
}
public int sumCoins(int[] ar, int sum) {
//if the sum is met, dont add any coins, just return 0
if(sum == S){
return 0;
}
//if the sum is greater, then return max value as it is impossible to get less sum
if(sum > S){
return Integer.MAX_VALUE;
}
//if the array is out of coins return max value
if(ar.length == 0){
return Integer.MAX_VALUE;
}
//if the sum is less than S and there is still more coins to use, keep checking
//add the first coin
int tmpSum = sum + ar[0];
//delete the first coin from the list
int[] tmp = Arrays.copyOfRange(ar, 1, ar.length);
//add one coin to the solution
int one = 1+sumCoins(tmp, tmpSum);
//don't add one coin to the solution
int two = sumCoins(ar,sum);
//see which is more minimized
return Math.min(one,two);
}
Requested Stack Trace:
Exception in thread "main" java.lang.StackOverflowError
at java.lang.Math.min(Math.java:879)
at java.util.Arrays.copyOfRange(Arrays.java:2623)
at Interview.sumCoins(Interview.java:28)
at Interview.sumCoins(Interview.java:32)
at Interview.sumCoins(Interview.java:32)
The answer to this question is in regards to how I was implementing my dynamic programming. I was using the original array in the case where you left the coin. this is incorrect. In more detail:
If you take the coin: get rid of the first (coin) index of the array, add the sum, add +1 for the number of coins.
If you don't take the coin: get rid of the first (coin) index of the array since you're leaving that coin to not be considered.
In my solution, I received a stackoverflow because I was going through the "leaving the coin" scenario infinite times as the array never decreased and I wasn't actually "leaving the coin".
Correct Code here:
private static final int S = 5;
public static int arr[] = {1,1,1,1,1};
public static void main(String[] args) {
Interview i = new Interview();
System.out.println(i.sumCoins(arr, 0));
}
public int sumCoins(int[] ar, int sum) {
//if the sum is met, dont add any coins, just return 0
if(sum == S){
return 0;
}
//if the sum is greater, then return global array (not local)
//length +1 as it's impossible to get more coins than indices
if(sum > S){
return arr.length+1;
}
//if the array is out of coins return max value
if(ar.length == 0){
return arr.length+1;
}
//if the sum is less than S and there is still more coins to use, keep checking
//add the first coin
int tmpSum = sum + ar[0];
//delete the first coin from the list
int[] tmp = Arrays.copyOfRange(ar, 1, ar.length);
//add one coin to the solution
int one = 1+sumCoins(tmp, tmpSum);
//don't add one coin to the solution
int two = sumCoins(tmp,sum);
//see which is more minimized
return Math.min(one,two);
}

How to measure the rate of events through a system

I need to measure that rate at which a software system is consuming messages from a message queue and report on that periodically.
Specifically, messages arrive from a message queueing system and I need to report (each second) on the number of messages received within a number of rolling windows - e.g. the last second, the last 5 seconds, the last 30 seconds, etc.
Whilst I'm sure I could build this, I'm not certain that I'd go about it in the most efficient manner! I'm also sure that there are libraries for doing this (I'm using the JVM, so Apache Commons Math springs to mind), but I don't even know the right words to Google for! :-)
Here is my solution based on exponential smoothing. It doesn't require any background threads. You would create 1 instance for each rolling window that you want to track. For each relevant event you would call newEvent on each instance.
public class WindowedEventRate {
private double normalizedRate; // event rate / window
private long windowSizeTicks;
private long lastEventTicks;
public WindowedEventRate(int aWindowSizeSeconds) {
windowSizeTicks = aWindowSizeSeconds * 1000L;
lastEventTicks = System.currentTimeMillis();
}
public double newEvent() {
long currentTicks = System.currentTimeMillis();
long period = currentTicks - lastEventTicks;
lastEventTicks = currentTicks;
double normalizedFrequency = (double) windowSizeTicks / (double) period;
double alpha = Math.min(1.0 / normalizedFrequency, 1.0);
normalizedRate = (alpha * normalizedFrequency) + ((1.0 - alpha) * normalizedRate);
return getRate();
}
public double getRate() {
return normalizedRate * 1000L / windowSizeTicks;
}
}
This is what I ended up writing.
package com.example;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class BucketCounter {
private final Lock rollLock = new ReentrantLock();
private final int[] bucketSizes;
private final int[] buckets;
private final int[] intervals;
private final AtomicInteger incoming = new AtomicInteger(0);
public BucketCounter(int... bucketSizes) {
if (bucketSizes.length < 1) {
throw new IllegalArgumentException("Must specify at least one bucket size");
}
this.bucketSizes = bucketSizes;
this.buckets = new int[bucketSizes.length];
Arrays.sort(bucketSizes);
if (bucketSizes[0] < 1) {
throw new IllegalArgumentException("Cannot have a bucket of size < 1");
}
intervals = new int[bucketSizes[bucketSizes.length - 1]];
}
public int count(int n) {
return incoming.addAndGet(n);
}
public int[] roll() {
final int toAdd = incoming.getAndSet(0);
rollLock.lock();
try {
final int[] results = new int[buckets.length];
for (int i = 0, n = buckets.length; i < n; i++) {
results[i] = buckets[i] = buckets[i] - intervals[bucketSizes[i] - 1] + toAdd;
}
System.arraycopy(intervals, 0, intervals, 1, intervals.length - 1);
intervals[0] = toAdd;
return results;
} finally {
rollLock.unlock();
}
}
}
Initialise it by passing the different time increments (e.g. 1, 5, 30). Then arrange for a background thread to call roll() every "time period". If you call it every second, then your buckets are 1, 5 and 30 seconds. If you call it every 5 seconds, then your buckets are 5, 25 and 150 seconds, etc. Basically, the buckets are expressed in "number of times roll() is called").
roll() also returns you an array of the current counts for each bucket. Note that these numbers are the raw counts, and are not averaged per time interval. You'll need to do that division yourself if you want to measure "rates" rather than "counts".
Finally, every time an event happens, call count(). I've set up a system with a few of these and I call count(1) on each message to count incoming messages, count(message.size()) on each message to count incoming byte rates, etc.
Hope that helps.
You could probably implement it as an interceptor, so search for interceptor combined with the message queue product name and the language name.

Tightest Byte Representation of YYYYMMDDHHMMSS?

I need to pack string with a UTC datetime, using the smallest number of bytes/characters. I only need precision to the second. Using .NET 4.0, what would be the most space-efficient way to pack this down? Ticks doesn't seem all that small.
All ideas appreciated.
Thanks.
EDIT: Thanks to Joel Coehoorn, the pack/unpack move is the best. Thanks! Here is some proof:
DateTimeOffset nowStamp = DateTimeOffset.UtcNow;
Console.WriteLine( nowStamp.ToString() ); // 9/9/2011 2:17:17 PM +00:00
Console.WriteLine( nowStamp.ToString( "u" ) ); // 2011-09-09 14:17:17Z
Console.WriteLine( nowStamp.Ticks.ToString() ); // 634511746376767889
Console.WriteLine( PackDate( nowStamp ) ); // 7R9qTgAAAAA=
Console.WriteLine( UnpackDate( PackDate( nowStamp ) ) ); // 9/9/2011 2:17:17 PM +00:00
Perhaps a variant on unix time (seconds since 1/1/1970 rather than milliseconds) base64 encoded.
//Helpers
private static DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static long toUnixTime(this DateTime d)
{
return (long)((d.ToUniversalTime() - Jan1st1970).TotalMilliseconds);
}
public static string Base64Encode(long toEncode)
{
return Convert.ToBase64String(BitConverter.GetBytes(toEncode));
}
//Encode
public static string PackDate(DateTime toPack)
{
return Base64Encode(toPack.toUnixTime()/1000);
}
//Decode
public static DateTime UnpackDate(string toUnpack)
{
long time = BitConverter.ToInt64(Convert.FromBase64String(toUnpack),0);
return Jan1st1970.AddSeconds(time); //you may or may not want a "ToLocaltime()" call here.
}
Note that all this was done without the aid of an IDE - there's likely a bug or two above. But it should get you started.
This should result in a fixed-width string. Since we're only doing seconds rather than milliseconds, you may find you always have some extra padding in the result that you don't need. You might even be able to get away with an int, rather than a long, which will cut the string in half. Be careful stripping that padding out, though, as the closer you get to 1970 the smaller the number, but the farther you get the larger and the more likely you are to need it. You need to be certain that your date value will fit within the new, smaller range for doing any trimming. For example, the current date fits comfortably within an int, but even 28 years from now will not. UInt32 will get you a little further into the future, but prevent you from using dates before 1970.
If you rellay need to save some bytes, and dead sure about date-time bounds, this solution would work:
internal class Program
{
private static DateTime _lbound = new DateTime(2011, 1, 1).ToUniversalTime();
private static DateTime _ubound = new DateTime(2013, 1, 1).ToUniversalTime();
private static int Pack(DateTime utcTime)
{
var totalSeconds = (_ubound - _lbound).TotalSeconds;
return (int) (utcTime - _lbound).TotalSeconds;
}
private static DateTime Unpack(int packedTime)
{
return _lbound.AddSeconds(packedTime);
}
private static void Check(DateTime time)
{
var unpacked = Unpack(Pack(time));
var areEquals = Math.Abs((time - unpacked).TotalSeconds) < 1.0;
Console.WriteLine("Verify: {0} - {1}", time, areEquals);
}
static void Main(string[] args)
{
Check(_lbound);
Check(_ubound);
Check(DateTime.UtcNow);
}
}
It will fit time representation, with 1 second precision in defined time bounds (from 2011 till 2013) in 4 bytes (int). However, IMO it's really bad from maintenance perspective of view.

ASP.net Cache Absolute Expiration not working

I am storing a single integer value in HttpContext.Cache with an absolute expiration time of 5 minutes from now. However, after waiting 6 minutes (or longer), the integer value is still in the Cache (i.e. it's never removed even though the absolute expiration has passed). Here is the code I am using:
public void UpdateCountFor(string remoteIp)
{
// only returns true the first time its run
// after that the value is still in the Cache
// even after the absolute expiration has passed
// so after that this keeps returning false
if (HttpContext.Current.Cache[remoteIp] == null)
{
// nothing for this ip in the cache so add the ip as a key with a value of 1
var expireDate = DateTime.Now.AddMinutes(5);
// I also tried:
// var expireDate = DateTime.UtcNow.AddMinutes(5);
// and that did not work either.
HttpContext.Current.Cache.Insert(remoteIp, 1, null, expireDate, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
}
else
{
// increment the existing value
HttpContext.Current.Cache[remoteIp] = ((int)HttpContext.Current.Cache[remoteIp]) + 1;
}
}
The first time I run UpdateCountFor("127.0.0.1") it inserts 1 into the cache with key "127.0.0.1" and an absolute expiration of 5 minutes from now as expected. Every subsequent run then increments the value in the cache. However, after waiting 10 minutes it continues to increment the value in the Cache. The value never expires and never gets removed from the Cache. Why is that?
It's my understanding that an absolute expiration time means the item will get removed approximately at that time. Am I doing something wrong? Am I misunderstanding something?
I'm expecting the value to be removed from the Cache after 5 minutes time, however it stays in there until I rebuild the project.
This is all running on .NET 4.0 on my local machine.
It turns out that this line:
HttpContext.Current.Cache[remoteIp] = ((int)HttpContext.Current.Cache[remoteIp]) + 1;
removes the previous value and re-inserts the value with NO absolute or sliding expiration time. In order to get around this I had to create a helper class and use it like so:
public class IncrementingCacheCounter
{
public int Count;
public DateTime ExpireDate;
}
public void UpdateCountFor(string remoteIp)
{
IncrementingCacheCounter counter = null;
if (HttpContext.Current.Cache[remoteIp] == null)
{
var expireDate = DateTime.Now.AddMinutes(5);
counter = new IncrementingCacheCounter { Count = 1, ExpireDate = expireDate };
}
else
{
counter = (IncrementingCacheCounter)HttpContext.Current.Cache[remoteIp];
counter.Count++;
}
HttpContext.Current.Cache.Insert(remoteIp, counter, null, counter.ExpireDate, Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
}
This will get around the issue and let the counter properly expire at the absolute time while still enabling updates to it.
Try using DateTime.UtcNow to calculate your timeout period instead of datetime.Now . You may be running into the issue described below:
absoluteExpiration Type:
System.DateTime The time at which the
inserted object expires and is removed
from the cache. To avoid possible
issues with local time such as changes
from standard time to daylight saving
time, use UtcNow rather than Now for
this parameter value. If you are using
absolute expiration, the
slidingExpiration parameter must be
NoSlidingExpiration.
There's a simpler answer than what smoak posted. Using that example as a starting point, the updated code below works and doesn't require a re-insert. The reason this works is because classes are reference types. Thus, when you update the counter inside the class instance it doesn't cause the cache to trigger an update.
public class IncrementingCacheCounter
{
public int Count;
}
public void UpdateCountFor(string remoteIp)
{
IncrementingCacheCounter counter = null;
if (HttpContext.Current.Cache[remoteIp] == null)
{
counter = new IncrementingCacheCounter { Count = 1};
HttpContext.Current.Cache.Insert(remoteIp, counter, null, DateTime.Now.AddMinutes(5), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
}
else
{
counter = (IncrementingCacheCounter)HttpContext.Current.Cache[remoteIp];
counter.Count++;
}
}

Resources