MomentJS add hours up to 24 - time

I have to solve this problem :
in code I might have moment times that look like this
{ start: '2020-08-03T00:00:00Z', end: '2020-08-03T23:59:59Z' }
or
{ start: '2020-08-03T15:11:51Z', end: '2020-08-04T15:11:50Z' }
If there is start time that is 00:00 I want to add 24 hours so that between start and end I get the whole day (meaning this objects represents one day)
But if start has any time more that 00:00, let's say 2020-08-03T15:11:51Z then I want to add precisely the amount of time which will result for end to be 2020-08-03T23:59:59Z
Right now in my case it adds 24 hours and it goes beyond 08-03 and results in 08-04 logically
I add time in moment like this:
.add(23, 'hours').add(59.999999, 'minutes').format()
Is there a simple way in moment to indicate this information like "if" and add necessary time up to 24 to fill the day ?
Thanks

If you want get everytime the end of day you can use .endOf('day') if you want get the end of the day
const obj1 = { start: '2020-08-03T00:00:00Z', end: '2020-08-03T23:59:59Z' }
console.log(moment(obj1.start).endOf('day'));
const obj2 = { start: '2020-08-03T15:11:51Z', end: '2020-08-04T15:11:50Z' }
console.log(moment(obj2.start).endOf('day'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>

Related

Calculate difference or delta between different events in logstash

Say I have a log file looking like this:
# time, count
2016-09-07 23:00:00, 1108731
2016-09-07 23:00:02, 1108733
2016-09-07 23:00:03, 1108734
Now, every next row contains a sum of all events that occurred in the past. I would like to use it in kibana and the natural way would be to have a count as a deltafied number.
So I expect an effect of:
# time, count, deltaCount
2016-09-07 23:00:00, 1108731, 0
2016-09-07 23:00:02, 1108733, 2
2016-09-07 23:00:03, 1108734, 1
How to achieve this in logstash. I know I could edit this files beforehand.
Thanks!
Solution #1: Write your plugin
One way to do it would be to create a plugin. The same problem is solved here. However, the filter that is posted there is not publicly available and, what is worse, it is actually 5 lines of code.
Solution #2: Ruby code snippet
I have found a solution in this thread on elastic forums: Keeping global variables in LS?!. The title says it all.
Cutting long story short, the solution goes as follows:
filter {
...
ruby {
init => "##previous_count = -1"
code => "
if (##previous_count == -1)
delta = 0
else
delta = event.get('count') - ##previous_count
end
event.set('requests', delta)
# remember event for next time
##previous_count = event.get('count')
"
}
}
Was not that hard after all.

Calculating days in Ruby

I have an issue where, I'm trying to work out if a certain alert on a webpage is calculating sums correctly. I'm using Capybara and Cucumber.
I have an alert that calculates records that expire within 30 days. When selecting this alert, the records are listed in a table and the date is presented in the following format, "1 feb 2016"
What I want to do is somehow take today's date, compare it to the date returned in the table and ensure that it's >= 30 days from the date in the alert.
I'm able to set today's date as the same format using Time.strftime etc.
When I try things like:
And(/^I can see record "([\d]*)" MOT is calculated due within 30 days$/) do |selection1|
today = Time.now.strftime('%l %b %Y')
thirty_days = (today + 30)
first_30day_mot = first('#clickable-rows > tbody > tr:nth-child(' + selection1 + ') > td:nth-child(3)')
if today + first_30day_mot <= thirty_days
puts 'alert correct'
else
(error handler here)
end
end
As you can see, this is quite a mess.
I keep getting the error TypeError: no implicit conversion of Fixnum into String
If anyone can think of a neater way to do this, please put me out of my misery.
Thanks
There are at least a couple of things wrong with your attempt.
You're converting dates to strings and then trying to compare lengths of time with strings. You should be converting strings to dates and then comparing them
#first returns the element in the page not the contents of the element
It's not 100% clear from your code what you're trying to do, but from the test naming I think you just want to make sure the date in the 3rd td cell (which is in the 1 feb 2016 format) of a given row is less than 30 days from now. If so the following should do what you want
mot_element = first("#clickable-rows > tbody > tr:nth-child(#{selection1}) > td:nth-child(3)")
date_of_mot = Date.parse(mot_element.text)
if (date_of_mot - Date.today) < 30
puts 'alert correct'
else
#error handler
end
Beyond that, I'm not sure why you're using #first with that selector since it seems like it should only ever match one element on the page, so you might want to swap that to #find instead, which would get you the benefits of Capybaras waiting behavior. If you do actually need #first, you might consider passing the minimum: 1 option to make sure it waits a bit for the matching element to appear on the page (if this is the first step after clicking a button to go to a new page for instance)
Convert selection1 to the string explicitly (or, better, use string interpolation):
first_30day_mot = first("#clickable-rows > tbody > tr:nth-child(#{selection1}) > td:nth-child(3)")
Also, I suspect that one line below it should be converted to integer to add it to today:
first_30day_mot.to_i <= 30
UPD OK, I finally got time to take a more thorough look at. You do not need all these voodoo magic with days calculus:
# today = Time.now.strftime('%l %b %Y') # today will be a string " 3 Feb 2016"
# thirty_days = (today + 30) this was causing an error
# correct:
# today = DateTime.now # correct, but not needed
# plus_30_days = today + 30.days # correct, but not needed
first_30day_mot = first("#clickable-rows > tbody > tr:nth-child(#{selection1}) > td:nth-child(3)")
if 30 > first_30day_mot.to_i
...
Hope it helps.
I'd strongly recommend not using Cucumber to do this sort of test. You'll find its:
Quite hard to set up
Has a high runtime cost
Doesn't give enough benefit to justify the setup/runtime costs
Instead consider writing a unit test of the thing that provides the date. Generally a good unit test can easily run 10 to 100 times faster than a scenario.
Whilst with a single scenario you won't experience that much pain, once you have alot of scenarios like this the pain will accumulate. Part of the art of using Cucumber is to get plenty of bang for each scenario you write.

How do I run an alarm from user input in swift

So far I have created a loop that takes a user input and compares it to the current time, and sounds an alarm if there is a match. When I run this it runs at 99% CPU usage and makes my computer nearly unusable. I am looking for a way to run this on a much lower priority or better yet, an alternative to a loop. All the other answers I have seen either don't address the user input through text, or isn't in swift. Any help is much appreciated and below is the function that compares the two times, the alarmHour and alarmMinute variables are the ones that the user enters.
func runTimer() {
var rightTime:Bool
do {
let date = NSDate()
let calendar = NSCalendar.currentCalendar()
let components = calendar.components(.CalendarUnitHour | .CalendarUnitMinute, fromDate: date)
let hour = String(components.hour)
let minutes = String(components.minute)
if (hour == globe.alarmHour && minutes == globe.alarmMinutes){
rightTime = true
} else {
rightTime = false
}
} while (rightTime == false)
if (rightTime == true) {
prepareAudio()
AlarmSound.play()
}
}
Ugh. Your do/while loop is in fact a very bad way to do it for the reasons you've outlined.
In most cases an NSTimer is the way to go. Take a look at the 'scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:` method.
You create a timer and schedule it and it calls your selector at the desired time.
NSTimers aren't totally exact. They can be off by around 50ms, but for displaying an alarm to the user that's fine.

Simple Add to time and compare GO

Hi I can't seem to get my head around the correct way to do time arithmetic in Go.
I have a time "object" later initialized to Now() and stored.
insertTime time.Time
Later, I need to see if the item is older than 15 minutes.
How do i do this?
Do I need to create a Duration of 15 Minutes add it to the current time and compare? If so, how do I do that?
func (Time) After will be helpful, I believe. Schema:
when := time.Now()
...
if time.Now().After(when.Add(15*time.Minute)) {
// Conditionally process something if at least 15 minutes elapsed
}
Instead of a variable, when could be a field of some struct, for example.
Alternative approach:
deadline := time.Now().Add(15*time.Minute)
...
if time.Now().After(deadline) {
// Conditionally process something if at least 15 minutes elapsed
}
I prefer the later version personally.

How to choose a random time once per hour

Suppose I want to run a task once per hour, but at a variable time during the hour. It doesn't have to be truly random; I just don't want to do it at the top of the hour every hour, for example. And I want to do it once per hour only.
This eliminates several obvious approaches, such as sleeping a random amount of time between 30 and 90 minutes, then sleeping again. It would be possible (and pretty likely) for the task to run several times in a row with a sleep of little more than 30 minutes.
The approach I'm thinking about looks like this: every hour, hash the Unix timestamp of the hour, and mod the result by 3600. Add the result to the Unix timestamp of the hour, and that's the moment when the task should run. In pseudocode:
while now = clock.tick; do
// now = a unix timestamp
hour = now - now % 3600;
hash = md5sum(hour);
the_time = hour + hash % 3600;
if now == the_time; then
do_the_work();
end
end
I'm sure this will meet my requirements, but I thought it would be fun to throw this question out and see what ideas other people have!
For the next hour to do work in, just pick a random minute within that hour.
That is, pick a random time for the next interval to do work in; this might be the same interval (hour) as the current interval (hour) if work has carried over from the previous interval.
The "time to sleep" is simply the time until then. This could also be execute "immediately" on a carry-over situation if the random time was before now: this will ensure that a random time is picked each hour, unless work takes more than an hour.
Don't make it more complex than it has to be - there is no reason to hash or otherwise muck with random here. This is how "Enterprise" solutions like SharePoint Timers (with an Hourly Schedule) work.
Schedule your task (with cron or the like) to run at the top of every hour.
At the beginning of your task, sleep for a random amount of time, from 0 to (60 - (the estimated running time of your task + a fudge factor)) minutes.
If you don't want your task to run twice simultaneously, you can use a pid file. The task can check - after sleeping - for this file and wait for the currently running task to finish before starting again.
I've deployed my suggested solution and it is working very well. For example, once per minute I sample some information from a process I'm monitoring, but I do it at variable times during the minute. I created a method of a Timestamp type, called RandomlyWithin, as follows, in Go code:
func (t Timestamp) RandomlyWithin(dur Timestamp, entropy ...uint32) Timestamp {
intervalStart := t - t % dur
toHash := uint32(intervalStart)
if len(entropy) > 0 {
toHash += entropy[0]
}
md5hasher.Reset()
md5hasher.Write([]byte{
uint8(toHash >> 24 & 255),
uint8(toHash >> 16 & 255),
uint8(toHash >> 8 & 255),
uint8(toHash & 255)})
randomNum := binary.BigEndian.Uint32(md5hasher.Sum(nil)[0:4])
result := intervalStart + Timestamp(randomNum)%dur
return result
}

Resources