Getting the number ordinal with Moment.js - momentjs

Is it possible to get a number's ordinal with Moment.js? For example if I pass in the number 7 and Momentjs would return '7th'
So far I have tried all these but none have worked
console.log(moment("12", "D Do")); // returns n {_isAMomentObject: true, _i: "12", _f: "D Do", _isUTC: false, _pf: Object…}
console.log(moment("3", "D Do")); // returns n {_isAMomentObject: true, _i: "3", _f: "D Do", _isUTC: false, _pf: Object…}
console.log(moment(3).format("D Do")); // returns '1 1st'
console.log(moment('3').format("D Do")); // returns '1 1st'
console.log(moment().day('3').format("Do")); // returns '9th'
console.log(moment().day(3).format("D Do")); // returns '9 9th'
EDIT: I should have mentioned that I am trying to process a date. So I get the date in this format DD-MM-YYYY. So if the date is 07-12-2015, I want to display it as 7th.

moment.localeData().ordinal(23)
// 23rd

I don't think Moment.js provides such an interface because it's use case is very limited.
If you don't have a date (e.g. a ranking) you could use the following:
function ordinal(number) {
switch (number) {
case 1:
case 21:
return number + 'st';
break;
case 2:
case 22:
return number + 'nd';
break;
case 3:
case 23:
return number + 'rd';
break;
default:
return number + 'th';
}
}
EDIT: Answer to the edited question:
You can do the following:
const date = '3-12-2015';
moment(date, 'DD-MM-YYYY').format('Do');
Demo
Documentation:
Parse: http://momentjs.com/docs/#/parsing/string-format/
Display: http://momentjs.com/docs/#/displaying/format/

Building off of the accepted answer above, you can avoid adding the day to an arbitrary date and instead just do:
moment('3', 'DD').format('Do');
EDIT
As pointed out in the comments, the above answer will return an invalid date for any number above 30, so a more stable solution that includes the 31st would be:
moment(`2012-10-${day}`).format('Do')

Related

How to find and print a dictionary key/value that matches user input?

I need to print a dictionary value that matches the input of the user. For example, if the user enters the course number CS101 the output will look like:
The details for CS101 are:
Room: 3004
Instructor: Haynes
Time: 8:00 a.m.
However, if the user enters an incorrect/invalid course number, I need to print out a message letting them know:
CS101 is an invalid course number.
I have tried if, for loops, and while loops. The problem is, every time I get the course info printed, the invalid course number message won't display because of KeyError. On the other hand, if I happen to "fix" the error message, then the course number info won't print out and instead will return a NameError / TypeError.
I will be honest, I have struggled for some time now with this, and I feel as though I am either assigning something incorrectly or printing incorrectly. But I am a beginner and I don't have a great grasp on Python yet, which is why I am asking for help.
Unfortunately, I am not allowed to create one entire dictionary to group everything in (which would have been easier for me), but instead, I have to create 3 dictionaries.
This is the code:
room = {}
room["CS101"] = "3004"
room["CS102"] = "4501"
room["CS103"] = "6755"
room["NT110"] = "1244"
room["CM241"] = "1411"
instructor = {}
instructor["CS101"] = "Haynes"
instructor["CS102"] = "Alvarado"
instructor["CS103"] = "Rich"
instructor["NT110"] = "Burkes"
instructor["CM241"] = "Lee"
time = {}
time["CS101"] = "8:00 a.m."
time["CS102"] = "9:00 a.m."
time["CS103"] = "10:00 a.m."
time["NT110"] = "11:00 a.m."
time["CM241"] = "1:00 p.m."
def info():
print(f'College Course Locater Program')
print(f'Enter a course number below to get information')
info()
get_course = input(f'Enter course number here: ')
print(f'----------------------------------------------')
course_num = get_course
number = course_num
name = course_num
meeting = course_num
if number in room:
if name in instructor:
if meeting in time:
print(f'The details for course {get_course} are: ')
print(f'Room: {number["room"]}')
print(f'Instructor: {name["instructor"]}')
print(f'Time: {meeting["time"]}')
else:
print(f'{course_num} is an invalid course number.')
I have also tried formatting dictionaries in this style:
time_dict = {
"CS101": {
"Time": "8:00 a.m."
},
"CS102": {
"Time": "9:00 a.m."
},
"CS103": {
"Time": "10:00 a.m."
},
"NT110": {
"Time": "11:00 a.m."
},
"CM241": {
"Time": "1:00 p.m."
},
}
I thank everyone in advance who has an advice, answer, or suggestions to a solution.
This code here is unnecessary, because you are essentially setting 4 variables all to the same value get_course:
course_num = get_course
number = course_num
name = course_num
meeting = course_num
This code here doesn't work because you are trying to find a key with string "room" in a dictionary that doesn't exist, and same with the other lines afterwards
print(f'Room: {number["room"]}')
print(f'Instructor: {name["instructor"]}')
print(f'Time: {meeting["time"]}')
I replaced the code above with this:
print(f'Room: {room[get_course]}')
print(f'Instructor: {instructor[get_course]}')
print(f'Time: {time[get_course]}')
This searches the dictionary variable room for the key get_course (ex. "CS101") and returns the value corresponding to that key. The same thing happens for the other lines, except with the dictionary instructor and the dictionary time.
Here is the final code:
room = {}
room["CS101"] = "3004"
room["CS102"] = "4501"
room["CS103"] = "6755"
room["NT110"] = "1244"
room["CM241"] = "1411"
instructor = {}
instructor["CS101"] = "Haynes"
instructor["CS102"] = "Alvarado"
instructor["CS103"] = "Rich"
instructor["NT110"] = "Burkes"
instructor["CM241"] = "Lee"
time = {}
time["CS101"] = "8:00 a.m."
time["CS102"] = "9:00 a.m."
time["CS103"] = "10:00 a.m."
time["NT110"] = "11:00 a.m."
time["CM241"] = "1:00 p.m."
def info():
print(f'College Course Locater Program')
print(f'Enter a course number below to get information')
info()
get_course = input(f'Enter course number here: ')
print(f'----------------------------------------------')
if get_course in room and get_course in instructor and get_course in time:
print(f'The details for course {get_course} are: ')
print(f'Room: {room[get_course]}')
print(f'Instructor: {instructor[get_course]}')
print(f'Time: {time[get_course]}')
else:
print(f'{get_course} is an invalid course number.')
Here is a test with the input "CS101":
College Course Locater Program
Enter a course number below to get information
Enter course number here: CS101
----------------------------------------------
The details for course CS101 are:
Room: 3004
Instructor: Haynes
Time: 8:00 a.m.
You could also do it like this. it'll probably take less time. The function is not very organize, try to organize it a little and it should work. I'm still not very familiar with adding codes on here.
course_info = {
'CS101': {
'Room': '3004',
'Instructor': 'Haynes',
'Time': '8:00 am'
},
'CS102': {
'Room': '4501',
'Instructor': 'Alvarado',
'Time': '9:00 a.m.'
},
'CS103': {
'Room': '6755',
'instructor': 'Rich',
'Time:': '10:00 am',
},
'NT110': {
'Room': '1244',
'instructor': 'Burkes',
'Time': '11:00 am'
},
'CM241': {
'Room': '1411',
'Instructor': 'Lee',
'Time': '1:00 pm'
},
}
get_course = input(f'Enter a course number: ')
try:
courses = course_info[get_course]
print(f'The details for for course {get_course} are: ')
print(f"Room: {courses['Room']}, Time: {courses['Time']},
Instructor: {courses['Instructor']}")
except KeyError:
print(f'Details not found for {get_course}')

MomentJS not returning correct info

I have an ISO formatted date that isn't being converted to the correct time, and I can't figure out why.
const m = (() => {
console.log("Here is the original time: " + periods)
const timeFixed = moment(periods).format("dddd, MMMM Do YYYY, h:mm:ss ");
console.log("Here is the fixed time: " + timeFixed)
return timeFixed;
})();
Using this, returns this:
Here is the original time: 2020-08-12T08:52:55Z
Here is the fixed time: Wednesday, January 1st 2020, 12:00:00
Any help given is appreciated as always.
Solved it, weirdly. It seems Moment was having an issue with the incoming format. Converted it to a string, then it handled it.
const m = (() => {
console.log("Here is the original time: " + periods)
const timeString = new Date(periods);
const timeFixed = moment(timeString).format("dddd, MMMM Do YYYY, hh:mm:ss ");
console.log("Here is the fixed time: " + timeFixed)
return timeFixed;
})();
Resulted in:
Here is the original time: 2020-08-12T08:52:55Z
Here is the fixed time: Wednesday, August 12th 2020, 09:52:55
Yes the time zone is off, but that's another problem for another day. Thanks for helping me find it.

momentjs calculates date difference incorrectly

In my angular web application, I want to compare two dates to see if a person is less than 18 years old when she/he entered the company. Here is the code I use to do this:
const dayOfBirth = moment(formControl.value, this.dateFormat, true).startOf('day');
const entranceDateControl = this.wizardFormGroup.get('entranceDate');
const entranceDate = moment(entranceDateControl.value, this.dateFormat, true).startOf('day');
// Check validation rule R3: Age is less than 18 compared to entrance date
const difference = moment.duration(Math.abs(entranceDate.diff(dayOfBirth)));
if (difference.years() < 18) {
const validationMessage = this.getValidationMessage('R3', formControlName);
return validationMessage ? validationMessage.message : null;
}
As you can see, I am using startOf('day') to get rid of any time component so that I only handle dates. I use diff() to get the difference between two dates and then duration() to convert the difference to years, months, days, etc. Using this code, the validation message should NOT show when the person is turning 18 years old on the day when she/he entered the company.
Upon testing this, I came across what is, in my opinion, strange behavior. Depending on months and years used, it gave different results. For instance, for these dates it was Ok:
dayOfBirth = 1998-03-01, 1998-04-01, ..., 2000-02-01
entranceDate = 2016-03-01, 2016-04-01, ..., 2018-02-01
But the following dates returned the validation message:
dayOfBirth = 2000-03-01, 2000-04-01, ..., 2002-02-01
entranceDate = 2018-03-01, 2000-04-01, ..., 2020-02-01
After these dates, i.e. using 2002-03-01 and onward, it works again. I also got wrong result for the dates preceding 1998-03-01.
Now, I had a closer look at the Duration object and I noticed that for the times where it was less than 18 years, it had calculated 864 milliseconds less then when it came to the right conclusion that it was 18 years between the dates.
Correct duration
----------------
dayOfBirth = 1998-03-01, 1998-04-01, ..., 2000-02-01
entranceDate = 2016-03-01, 2016-04-01, ..., 2018-02-01
Duration = 568080000000 ms
Wrong duration
--------------
dayOfBirth = 2000-03-01, 2000-04-01, ..., 2002-02-01
entranceDate = 2018-03-01, 2000-04-01, ..., 2020-02-01
Duration = 567993600000 ms
Duration difference
-------------------
568080000000 - 567993600000 = 86400000 ms = 24 hours = 1 day
Has anyone an explanation for this? Can it be considered a bug in momentjs? Any viable workaround for this?
I didn't go into details in moment source code but it seems duration() is playing tricks with you. Simplify the code and rely only on diffas follow and you should be good (at least it seems to work for the samples you provided). And it's easier on the eyes :)
const moment = require('moment')
const dayOfBirth = moment('2000-03-01').startOf('day');
const entranceDate = moment('2018-03-01').startOf('day');
const difference = entranceDate.diff(dayOfBirth, 'years')
if (difference < 18) {
console.log( '<18')
} else {
console.log( '>=18')
}
will output >=18

Delphi displays strange results for operations with negative values to TDateTime

We have a solution in Delphi that calculates a travel's duration of a given vehicle, for example, 20 minutes, 25 minutes and so on. However, sometimes we have to antecipate the travel's start time, from a specific datetime, for example 09:00 to 08:40. Then, we need to substract a negative value from a TDateTime variable (travel's start), in this case, something like "-00:20". To do this, we multiply the datetime value by -1 (for example MyDiffDateTimeVariable * -1). The output we got is very strange, sometimes we obtain the exactly opposite behavior. In other case, an operation to extract 20 minutes results in a difference of two days from the original datetime.
Here is a sample console application that simulate our situation, with the current outputs, and what we will expected:
program DateTimeSample;
uses
System.SysUtils, System.DateUtils;
var
LDate1: TDateTime;
LDate2: TDateTime;
begin
LDate1 := IncMinute(0, 20);
LDate2 := IncMinute(0, -20);
WriteLn('Date1: ' + DateTimeToStr(LDate1));
// Output = Date1: 30/12/1899 00:20:00 [OK]
WriteLn('Date2: ' + DateTimeToStr(LDate2));
// Output = Date2: 29/12/1899 23:40:00 [OK]
WriteLn('-----');
WriteLn('Date1: ' + DateTimeToStr(LDate1 * -1));
// Output = Date1: 30/12/1899 00:20:00 [Expected 29/12/1899 23:40:00]
WriteLn('Date2: ' + DateTimeToStr(LDate2 * -1));
// Output = Date2: 31/12/1899 23:40:00 [Expected 30/12/1899 00:20:00]
ReadLn;
end.
When you inspect the value casted to double, you can see:
double(LDate1) = 0.0138888888888889
double(LDate2) = -1.98611111111111
Seems like a bug to me, because with today it returns:
double(LDate1) = 43168,0138888889
double(LDate2) = 43167,9861111111
Edit: Hmm, according the documentation, it is not a bug, it is a feature :-)
When working with negative TDateTime values, computations must handle time portion separately. The fractional part reflects the fraction of a 24-hour day without regard to the sign of the TDateTime value. For example, 6:00 A.M. on December 29, 1899 is –1.25, not –1 + 0.25, which would equal –0.75. There are no TDateTime values from –1 through 0.
Karel's answer explains what's happening. Basically, TDateTime is represented as a Double, but that doesn't mean you can work with it in the same way as you normally would a Double value. It's internal structure carries particular semantics that if you don't handle them correctly, you're bound to get some peculiar behaviour.
The key mistake you're making is in taking the negative of a date-time value. This concept doesn't really make sense. Not even if you look at dates in BC, because the calendar system has changed a number of times over the years.
This is the main reason you should favour library routines that deal with the nuances of the internal structure (whatever your platform). In Delphi that means you should use the SysUtils and DateUtils routines for working with dates and times.
You seem to be trying to hold duration as a TDateTime value. You'd be much better off determining your preferred unit of measure and using Integer (perhaps Int64) or Double (if you need support for fractions of a unit). Then you can add or subtract, preferably using library routines, the duration from your start or end times.
The following code demonstrates some examples.
var
LStartTime, LEndTime: TDateTime;
LDuration_Mins: Integer;
begin
{ Init sample values for each calculation }
LStartTime := EncodeDateTime(2018, 3, 9, 8, 40, 0, 0);
LEndTime := EncodeDateTime(2018, 3, 9, 9, 0, 0, 0);
LDuration_Mins := 20;
{ Output result of each calculation }
Writeln(Format('Whole Duration: %d', [MinutesBetween(LStartTime, LEndTime)]));
Writeln(Format('Frac Duration: %.6f', [MinuteSpan(LStartTime, LEndTime)]));
Writeln(Format('Start Time: %s', [FormatDateTime('yyyy-mm-dd hh:nn:ss', IncMinute(LEndTime, -LDuration_Mins))]));
Writeln(Format('End Time: %s', [FormatDateTime('yyyy-mm-dd hh:nn:ss', IncMinute(LStartTime, LDuration_Mins))]));
end;
Additional Considerations
You said you're dealing with vehicle travel times. If you're dealing with long-haul travel you might have some other things to think about.
Daylight saving: If a vehicle starts its journey shortly before DST changes and ends after, you need to take this into account when calculating a missing value. Perhaps easiest would be to convert date-time values to UTC for the calculation. Which leads to...
Time zone changes: Again, unless your code is time-zone aware you're bound to make mistakes.
Compiler always appears to treat TDateTime as positive when doing numerical operations on it. Try this:
uses
System.SysUtils, System.DateUtils;
function InvertDate(ADateTime: TDateTime): TDateTime;
var
LMsec: Int64;
begin
LMsec := MillisecondsBetween(ADateTime, 0); //Always Positive
if ADateTime > 0 then
LMsec := 0 - LMsec;
Result := IncMillisecond(0, LMsec);
end;
var
LDate1: TDateTime;
LDate1Negative: TDateTime;
LDate2: TDateTime;
begin
try
LDate1 := IncMinute(0, 20);
LDate2 := IncMinute(0, -20);
WriteLn('Date1: ' + DateTimeToStr(LDate1));
// Output = Date1: 30/12/1899 00:20:00 [OK]
WriteLn('Date2: ' + DateTimeToStr(LDate2));
// Output = Date2: 29/12/1899 23:40:00 [OK]
WriteLn('-----');
WriteLn('Date1: ' + DateTimeToStr( InvertDate(LDate1) ));
// Output = Date1: Expected 29/12/1899 23:40:00
WriteLn('Date2: ' + DateTimeToStr( InvertDate(LDate2) ));
// Output = Date2: 30/12/1899 00:20:00
ReadLn;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

Getting the month number by month name with Moment.js

I am trying to return the month number passing the month name using MomentJS. For example if I pass "July" to moment() I would expect 7 to be returned.
After reading through the docs I tried several different ways, and this way came close...
console.log(moment().month("July"));
In the console, buried in the response I could see this...
_monthsParse: Array[7]
Could anyone please tell me how to return the month number using MomentJS correctly?
Try :
moment().month("July").format("M");
Relevant documentation: http://momentjs.com/docs/#/get-set/month/
alert(moment().month("July").format("M"));
<script src="https://momentjs.com/downloads/moment.min.js"></script>
Anybody looking to get month name from month number then you can try :
const number = 1; // 0 = Jan & 11 = Dec
moment().month(number).format("MMM"); // Feb
Use following to get full month name :
const number = 1; // 0 = January & 11 = December
moment().month(number).format("MMMM"); // February
To use simple month number try this:
const month = 2 //Feb
moment(month, 'M').format('MMMM');
##get month name in moment js with node js
moment() give today date
format("DD-MMMM-YYYY") / output 18-May-2020
format("DD-MM-YYYY") / output 18-05-2020
- sperator you can use /
```
var moment = require('moment');
m_date = moment().format("DD-MMMM-YYYY");
console.log("moment date :", m_date)
```
##output
```
moment date : 18-May-2020
```
Read Officail Docdescription here

Resources