How do I optimise displaying time durations in a human-readable way? - mysql

I want to implement a functionality for my project. It's very similar to a feature on Stack Overflow where user post requests and gets responses. Here on Stack Overflow we see post marked as 4 seconds ago, 22 seconds ago, 1 minute ago, 5 minutes ago etc. I want to implement the same.
I am storing the request posted time in a timestamp variable in MySQL, then subtracting NOW() - stored_time to get the seconds. Then writing some logic, like
if less than 60 seconds, display 60 seconds ago
if difference in between 60 to 3600, display in minutes
and so on. This long logic is written in Perl. I want to avoid that. Is there any good way to achieve the same thing? I am open to change the MySQL table and data type.

Send number of elapsed seconds to client and convert it to human-readable text in JavaScript.

Retrieve the datestamps as DateTime objects. You don't show any details of your database, so I have to skip that step in my answer.
use DateTime qw();
use DateTime::Format::Human::Duration qw();
for my $seconds (555, 5555, 555555, 5555555) {
my $now = DateTime->now;
my $before = $now->clone->subtract(seconds => $seconds);
my $formatted = DateTime::Format::Human::Duration
->new->format_duration($before - $now);
$formatted =~ s/(?:,| and).*//;
print "about $formatted ago\n";
}
# about 9 minutes ago
# about 1 hour ago
# about 6 days ago
# about 2 months ago

Related

Tcl script to calculate a duration

I need to create a script whithin I can calcute a durations here an example :
assign duration1 5.hours
assign duration2 4.minutes
assign duration3 10.seconds
assign seconds [calc_duration [getVar duration1] + [getVar duration2] + [getVar duration3]]*
I want to get as a respons (seconds) for the example I would have "18250" seconds.
can you please help me with this.
Thanks.
The clock add command can do calculations with durations, but it needs a base time to work with. That's important because, for example, not all months are the same number of days long, and not all days are the same number of hours because of DST rules (which are themselves not the same every year). If you're only working with the small units and not too many of them, you can ignore this and use 0 (the start of the Unix epoch) as the base time.
set seconds [clock add 0 5 hours 4 minutes 10 seconds]
But if you're working with longer amounts of time, you'll need to be more careful. clock add still has the tools, but you'll have to choose the base timestamp correctly and specify your locale of interest.
# You're really supposed to scan with a format, but I'm lazy
set baseTimestamp [clock scan "4/4/2022 10:30 EST"]
set timezone :America/New_York; # EST/EDT
set timeBits {5 months 4 days 3 hours 2 minutes 1 second}
# Do the time arithmetic
set targetTimestamp [clock add $baseTimestamp {*}$timeBits -timezone $timezone]
# Convert into an elapsed number of seconds
set seconds [expr {$targetTimestamp - $baseTimestamp}]
# 13575721 seconds is a fair while...

How to create a json for python which shown change in speed every few minutes

I am new to json and trying to create a config.json which will be used in a python program(for esp32 board). This config.json will include various speeds at different times and this will repeat every 24 hours. For example: for first 30 minutes, speed will be 40. For next 3 hrs, speed will be 60 and so on. and after 24 hours, the cycle will repeat.
I am currently doing this, but seems like this is wrong.
{[
{"speed":30,"time":60},
{"speed":40,"time":60},
{"speed":60,"time":60},
{"speed":90,"time":60},
{"speed":50,"time":60}
]}
Here 60 stands for 60 seconds

JIRA REST API Sprint Issue route - timeSpent and timeSpentSeconds don't match

I'm currently using the JIRA REST API to retrieve the amount of time spent on a ticket in a project using the following route:
/rest/agile/1.0/board/{boardId}/sprint/{sprintId}/issue
Within one of the issues, I receive the following data relating to time:
"timetracking": {
"remainingEstimate": "9w 1d",
"timeSpent": "4d",
"remainingEstimateSeconds": 1324800,
"timeSpentSeconds": 115200
},
When converting the seconds to days, it results in 1.33333333 days, where as the timeSpent specifies 4 days.
Why does timeSpent and timeSpentSeconds not add up, and is there a way to resolve the issue to ensure that they do match?
I figured this out. As it turns out, it does not work on a 24 hour period, i.e. 1d does not equal 86400, but rather it works on hours spent on the project per day, in my case, 8h. Therefore the seconds is 4 * 8 which equals 1.33333... days.

Calculate date from numeric value

The number 71867806 represents the present day, with the smallest unit of days.
Sorry guy's, caching owned me, it's actually milliseconds!
How can I
calculate the currente date from it?
(or) convert it into an Unix timestamp?
Solution shouldn't use language depending features.
Thanks!
This depends on:
What unit this number represents (days, seconds, milliseconds, ticks?)
When the starting date was
In general I would discourage you from trying to reinvent the wheel here, since you will have to handle every single exception in regards to dates yourself.
If it's truly an integer number of days, and the number you've given is for today (April 21, 2010, for me as I'm reading this), then the "zero day" (the epoch) was obviously enough 71867806 days ago. I can't quite imagine why somebody would pick that though -- it works out to roughly 196,763 years ago (~194,753 BC, if you prefer). That seems like a strange enough time to pick that I'm going to guess that there's more to this than what you've told us (perhaps more than you know about).
It seems to me the first thing to do is verify that the number does increase by one every 24 hours. If at all possible keep track of the exact time when it does increment.
First, you have only one point, and that's not quite enough. Get the number for "tomorrow" and see if that's 71867806+1. If it is, then you can safely bet that +1 means +1 day. If it's something like tomorrow-today = 24, then odds are +1 means +1 hour, and the logic to display days only shows you the "day" part. If it's something else check to see if it's near (24*60, which would be minutes), (24*60*60, which would be seconds), or (24*60*60*1000, which would be milliseconds).
Once you have an idea of what kind of units you are using, you can estimate how many years ago the "start" date of 0 was. See if that aligns with any of the common calendar systems located at http://en.wikipedia.org/wiki/List_of_calendars. Odds are that the calendar you are using isn't a truly new creation, but a reimplementation of an existing calendar. If it seems very far back, it might be an Julian Date, which has day 0 equivalent to BCE 4713 January 01 12:00:00.0 UT Monday. Julian Dates and Modified Julian dates are often used in astronomy calculations.
The next major goal is to find Jan 1, 1970 00:00:00. If you can find the number that represents that date, then you simply subtract it from this foreign calendar system and convert the remainder from the discovered units to milliseconds. That will give you UNIX time which you can then use with the standard UNIX utilities to convert to a time in any time zone you like.
In the end, you might not be able to be 100% certain that your conversion is exactly the same as the hand implemented system, but if you can test your assumptions about the calendar by plugging in numbers and seeing if they display as you predicted. Use this technique to create a battery of tests which will help you determine how this system handles leap years, etc. Remember, it might not handle them at all!
What time is: 71,867,806 miliseconds from midnight?
There are:
- 86,400,000 ms/day
- 3,600,000 ms/hour
- 60,000 ms/minute
- 1,000 ms/second
Remove and tally these units until you have the time, as follows:
How many days? None because 71,867,806 is less than 86,400,000
How many hours? Maximum times 3,600,000 can be removed is 19 times
71,867,806 - (3,600,000 * 19) = 3,467,806 ms left.
How many minutes? Maximum times 60,000 can be removed is 57 times.
3,467,806 - (60,000 * 57) = 47,806 ms left
How many seconds? Maximum times 1,000 can be removed is 47 times.
47,806 - (1,000 * 47) = 806
So the time is: 19:57:47.806
It is indeed a fairly long time ago if the smallest number is in days. However, assuming you're sure about it I could suggest the following shell command which would be obviously not valid for dates before 1st Jan. 1970:
date -d "#$(echo '(71867806-71853086)*3600*24'|bc)" +%D
or without bc:
date -d "#$(((71867806 - 71853086) * 3600 * 24))" +%D
Sorry again for the messy question, i got the solution now. In js it looks like that:
var dayZero = new Date(new Date().getTime() - 71867806 * 1000);

Ordering by created_at in unit tests with generated data in rails

I have a bit of code that basically displays the last x (variable, but let's say x is 20 here) updates made in a given table. In one of the unit tests for it, I have this snippet:
EditedItem.push_to_queue(hiddennow)
#create some new entries and save them
20.times{ EditedItem.push_to_queue(random_item) }
Queue.get_entries.each{|entry| assert_not_equal too_far_down, entry}
May or may not be pretty, but it gets the intention across. The hiddennow object has been pushed down in the queue too far and should no longer be returned when get_entries is called.
#this works
SearchObject.find(:all, :order => "id desc")
#this does not, unless the 20.times loop has sleep(1) or something
SearchObject.find(:all, :order => "created_at desc")
This is simplified down a bit, but it looks like the 20.times loop adds things fast enough that the order by clause on created_at cannot distinguish. My questions are, am I doing something fundamentally wrong? If not, what is the better approach to writing a test along these lines?
DigitalRoss is right. created_at has a one second granularity.
One option is to set the created_at when you create the objects:
old = EditItem.new(:created_at => 1.second.ago)
older = EditItem.new(:created_at => 2.seconds.ago)
Another option is to actually use stubbing to mess with the Time class. The following would work with Rspec, but could be easily accomplished with other mocking frameworks like Mocha.
#seconds = Time.now.to_i
Time.stub!(:now).and_return{Time.at(#seconds += 5) }
This will return a time 5 seconds greater than the previous each time you call Time.now.
I'd recommend the first approach if you can make it work, since it's more clear what you're doing and less likely to have unintended consequences.
Times related to files and records (and specifically those times in Rails) are typically kept in Unix time, or POSIX time, This format keeps the number of seconds since 1970 in an arithmetic type.
So, time for these purposes has a 1 second granularity.
Rails can't order hiddennow vs the random items without at least a one second delay in between, and the set of 20 won't be ordered at all.
Are these answers still correct in rails 5 or 6?
Suppose there is a legacy default scope on the User model:
#app/models/user.rb
class User
default_scope { order created_at: :desc }
end
The following rspec test
describe 'ordering in rails' do
before(:each) do
(0..9).each_with_index do |i|
create :user, email: "#{i}#example.com"
end
end
it 'preserves order' do
puts User.pluck(:id, :created_at, :email)
expect(User.all.pluck(:email).map(&:first)).to eq %w(9 8 7 6 5 4 3 2 1 0)
end
end
yields the following output:
7602
2020-01-07 09:33:14 UTC
9#example.com
7601
2020-01-07 09:33:14 UTC
8#example.com
7600
2020-01-07 09:33:14 UTC
7#example.com
7599
2020-01-07 09:33:14 UTC
6#example.com
7598
2020-01-07 09:33:14 UTC
5#example.com
7597
2020-01-07 09:33:14 UTC
4#example.com
7596
2020-01-07 09:33:14 UTC
3#example.com
7595
2020-01-07 09:33:14 UTC
2#example.com
7594
2020-01-07 09:33:14 UTC
1#example.com
7593
2020-01-07 09:33:14 UTC
0#example.com
.
Finished in 0.30216 seconds (files took 1.34 seconds to load)
1 example, 0 failures
so despite all the models being created at the same second, there is a consistent ordering. Looking at this rails 6 merge request, it looks like that by rails 5 there is an implicit ordering on the primary key. I wonder if the id is being used to break ties in later versions of rails?