MomentJS - making fromNow() round down - momentjs

I was using the following code to calculate the age of a person:
var year = 1964;
var month = 1;
var day = 20;
var age = moment(year + '-' + month + '-' + date, 'YYYY-MM-DD').fromNow(true);
The problem with fromNow() is that it rounds the number up or down depending on the decimal point. I would like it to only round down. In the above example the person's real age is 51 but it's returning 52 because his age is actually something like 51.75.
If I use diff() instead it rounds down which is perfect. But it doesn't give me the pretty text 51 years old.
var age = moment().diff([year, month - 1, date], 'years');
My question is, is there a way to make fromNow() round down?

You can configure a custom rounding function:
moment.relativeTimeRounding(Math.floor)

The provided solution is correct but I thought I'd add a little explanation as this was the first google result.
Say I have a scenario where I want dates that were 1m 30s ago to display a minute ago rather than two minutes ago:
const minuteAndAHalfAgo = new Date();
minuteAndAHalfAgo.setMinutes(minuteAndAHalfAgo.getMinutes() - 1);
minuteAndAHalfAgo.setSeconds(minuteAndAHalfAgo.getSeconds() - 30)
moment.relativeTimeRounding(Math.floor);
console.log(moment(minuteAndAHalfAgo).fromNow()); // a minute ago
the relativeTimeRounding function takes a function as an argument which in our case is Math.floor which means the relative time evaluation will be rounded down. This can be found in the docs https://momentjs.com/docs/#/customization/relative-time-rounding/ - you can also specify a relativeTimeThreshold — the point at which to round the number.

Related

Syntax in R, Overtime Pay

I am an intro into computer science student and have learned more on how to use python and am now learning R. I'm not used to R, and I've figured out how to calculate overtime pay, but I am not sure what is wrong with my syntax:
computePay <- function(pay,hours){
}if (hours)>=40{
newpay = 40-hours
total=pay*1.5
return(pay*40)+newpay*total
}else{
return (pay * hours)
}
How would I code this correctly?
Without looking at things like vectorization, a direct correction of your function would look something like:
computePay <- function(pay,hours) {
if (hours >= 40) {
newpay = hours - 40
total = pay * 1.5
return(pay*40 + newpay*total)
} else {
return(pay * hours)
}
}
This supports calling the function with a single pay and a single hours. You mis-calculated newpay (which really should be named something overhours), I corrected it.
You may hear people talk about "avoiding magic constants". A "magic constant" is a hard-coded number within code that is not perfectly clear and/or might be useful to allow the caller to modify. For instance, in some contracts it might be that overtime starts at a number other than 40, so that might be configurable. You can do that by changing the formals to:
computePay <- function(pay, hours, overtime_hours = 40, overtime_factor = 1.5)
and using those variables instead of hard-coded numbers. This allows the user to specify other values, but if not provided then they resort to sane defaults.
Furthermore, it might be useful to call it with a vector of one or the other, in which case the current function will fail because if (hours >= 40) needs a single logical value, but (e.g.) c(40,50) >= 40 returns a logical vector of length 2. We do this by introducing the ifelse function. Though it has some gotchas in advanced usage, it should work just fine here:
computePay1 <- function(pay, hours, overtime_hours = 40, overtime_factor = 1.5) {
ifelse(hours >= overtime_hours,
overtime_hours * pay + (hours - overtime_hours) * overtime_factor * pay,
pay * hours)
}
Because of some gotchas and deep-nested readability (I've seen ifelse stacked 12 levels deep), some people prefer other solutions. If you look at it closer, you may find that you can take further advantage of vectorization and pmax which is max applied piece-wise over each element. (Note the difference of max(c(1,3,5), c(2,4,4)) versus pmax(c(1,3,5), c(2,4,4)).)
Try something like this:
computePay2 <- function(pay, hours, overtime_hours = 40, overtime_factor = 1.5) {
pmax(0, hours - overtime_hours) * overtime_factor * pay +
pmin(hours, overtime_hours) * pay
}
To show how this works, I'll expand the pmax and pmin components:
hours <- c(20, 39, 41, 50)
overtime_hours <- 40
pmax(0, hours - overtime_hours)
# [1] 0 0 1 10
pmin(hours, overtime_hours)
# [1] 20 39 40 40
The rest sorts itself out.
Your "newpay*total" expression is outside the return command. You need put it inside the parentheses. The end bracket at the beginning of the second line should be moved to the last line. You also should have "(hours>=40)" rather than "(hours)>=40". Stylistically, the variable names are poorly chosen and there's no indentation (this might have helped you notice the misplaced bracket). Also, the calculation can be simplified:
total_pay = hourly_wage*(hours+max(0,hours-40)/2))
For every hour you work, you get your hourly wage. For every hour over 40 hours, you get your hourly wage plus half your hourly wage. So the total pay is wage*(total hours + (hours over 40)/2). Hours over 40 is either going to be total hours minus 40, or zero, whichever is larger.

How to show equally spaced axis for datetime for billing cycle related data on highcharts

I want to show billing cycle data using highcharts where x-axis is datetime. Requirement is to show only 5 labels. But billing cycle start and billing cycle end date should always be shown and we have to display remaining days in equal intervals.
So for example
if billing cycle - 24-06-2015 to 23-07-2015
Labels to show: 24/06 01/07 08/07 15/07 23/07
if billing cycle - 15-06-2015 to 14-07-2015
Labels to show: 15/06 22/06 29/06 06/07 14/07
Any help/hint would help me a lot :)
Simply use tickPositioner - and write your logic. In short, it would be:
tickPositioner: function () {
var ticks = [],
min = this.min,
max = this.max,
range = max - min,
interval = range / 5;
while (min < max) {
ticks.push(min);
min += interval;
}
return ticks;
}
Demo (for yAxis, but it doesn't matter): http://jsfiddle.net/qkLd44h1/
PS: You may want to edit a bit algorithm above, to round ticks to fall on a specific day (like always 1st of the month etc).

Converting a 19 digits time stamp to a real time (from .zvi file format)

After a long day of research,
Is anybody knows how to convert a 19 digits time stamp from the metadata of .zvi file (produce by axiovision, Zeiss) to a real time format ? (The output probably includes milliseconds)
An example time-stamp is: 4675873294709522577
Thanks !
Arnon
Matlab solution:
The main issue is not the x2mdate conversion (which simply adds the number of days between the year zero, when Matlab starts counting, and the year 1900, when Excel/zvi starts counting), but the same class issue as described above. This conversion to double can be done with typecast in Matlab:
myZVI = 4675946358764751269;
timestampDouble = typecast(int64(myZVI),'double');
myTime = datestr(timestampDouble + 693960, 'dd-mmm-yyyy HH:MM:SS.FFF');
693960 is the number of days between year zero and 1900; if you don't need an absolute date but just the difference between two timestamps, you don't even need this; for instance the interval between two of my video frames can be calculated like this:
myZVI2 = 4675946358764826427;
timestampDouble2 = typecast(int64(myZVI2),'double');
myTimeDifference = datestr(timestampDouble2 - timestampDouble,'SS.FFF');
hope this helps:-)
This is a Microsoft OLE Automation Date. But you've read it as a 64-bit long integer instead of the 64-bit double that it should be.
You didn't specify a language, so I will pick C#:
long l = 4675873294709522577L;
byte[] b = BitConverter.GetBytes(l);
double d = BitConverter.ToDouble(b, 0);
Debug.WriteLine(d); // 41039.901598693
DateTime dt = DateTime.FromOADate(d);
Debug.WriteLine(dt); // 5/10/2012 9:38:18 PM
More information in this thread.
An OLE Automation Date is basically the number of whole 24-hour days since 1/1/1900 without any particular time zone reference.

Calculating wage by hours worked

Hey all, i am trying to figure out how to calculate the wage for an employee when they clock out. This is the code i am currently using:
Dim theStartTime As Date
Dim theEndTime As Date
Dim totalTime As String
theStartTime = "16:11:06"
theEndTime = "18:22:01"
totalTime = Format(CDbl((theEndTime - theStartTime) * 24), "#0.0")
So workable hours would be: 2h 11m
Right now, with my calculation code above, i get 2.2. What would i need to add in order to get it to calculate the correct time of 2:11 instead of 2:20?
David
Note that 2.2 hours is not 2:20, it's 2:12.
Change
Format(CDbl((theEndTime - theStartTime) * 24), "#0.0")
to
Format(theEndTime - theStartTime, "h:mm")
You're getting the right value, just rounding it off when you print. theEndTime - theStartTime is a time span equal to the difference between the two times. As you discovered, multiplying it by 24 will give you the number of hours different. However, you then have to divide by 24 again to use date/time formatting.
Check out all the ways to format dates and time in VB6.
First, I highly suggest going to the .NET framework (with it's easy-to-use TimeSpan class) if possible.
But, dealing in VB6 you should be able to use the DATEDIFF function (and it's been many years since I've touched VB6 so the specific syntax might be a bit off
Dim iHours As Integer, iMins As Integer
iMins = DateDiff("n", theStartTime, theEndTime)
iHours = iMins / 60
iMins = iMins Mod 60
You should also try casting it to the Currency type which can represent all numeric values (within 4 digits to the left of decimal point and 15 digits to the right).
Format(CCur((theEndTime - theStartTime) * 24), "#0.00")

Constant Pointer / structs

In my programming class, we have
struct Time {
int hours, min, sec;
}
We are to create a method to compute the difference between two times:
Time *timeDiff(const Time *t1, const Time *t2)
I thought I could create the time difference by getting everything in seconds, and then subtracting the two values, but it seems like extra work to do something like
long hour1 = t1->hours;
long min1 = t1->min;
long sec1 = t1->sec;
And then using these values to get the time in seconds, do something similar for the second time, and then subtract. Any thoughts? Thanks!
The way you've described it sounds exactly right. I might do something like
int sec = t1->sec + 60*(t1->min + 60*t1->hours);
Then similarly for t2, then subtract one from the other and break the result down into minutes and hours.

Resources