Closed lschierer closed 2 years ago
Hello, thanks for the question. I think the documentation is confusing if not incorrect, sorry about that.
This example shows where dates can appear in a Gedcom file and how one can extract them. Now, Gedcom dates can take various forms (range of dates, uncertainty, etc.), this is why the method valueAsDate
will return a ValueDate
. In practice, this type will be most of the type an instance of ValueDatePunctual
, which you can check by querying the field isDatePunctual
and implies that your object has a field date
of type ValuePartDate
. You can pass this date
object to the method toJsDate
(note that it expects a ValuePartDateYear
but it should actually be ValuePartDate
; though both reduce to the exact same type). This method will attempt to convert this date into a JavaScript standard date object.
Here is a complete example:
import { toJsDate } from 'read-gedcom';
const dates: (Date | null)[] = gedcom
.getIndividualRecord('@I1@')
.getEventBirth()
.getDate() // 24 MAY 1819
.valueAsDate() // { date: { day: 24, month: 5, year: 1819, calendar: { isGregorian: true, ... }, ... }, ... }
.map(d => {
if(d && d.isDatePunctual) {
const datePart = d.date; // { day: 24, month: 5, year: 1819, calendar: { isGregorian: true, ... }, ... }
return toJsDate(datePart); // Date | null
} else {
return null;
}
});
Note that these dates are always expressed in the UTC-0 timezone, not in your local timezone. You may for example use the following methods to access this object correctly:
const date: Date = ...; // toJsDate
console.log(date.toISOString()); // 1819-05-24T00:00:00.000Z
console.log(date.getUTCFullYear()); // 1819
console.log(date.getUTCMonth()); // 4 (in JS months start at 0)
console.log(date.getUTCDate()); // 24
I'll leave the ticket open until I fix the documentation. Feel free to ask more questions in the meantime.
using read-gedcom@0.3.1 and transpiling using Hugo 0.101.0, I am getting "Uncaught ReferenceError: toJsDate is not defined" in my browser's javascript console. I am able to successfully console.log the gedcom.getIndividualRecord('@I1@').toString()
if ((typeof(this.myGedId) !== 'undefined') && (this.myGedId !== '')) {
console.log(`in birthday, GedId is ${this.myGedId}`);
const i = g.getIndividualRecord(`${this.myGedId}`);
console.log('individual is ' + i.toString());
this.myBirthday = g.getIndividualRecord(`${this.myGedId}`)
.getEventBirth()
.getDate()
.valueAsDate()
.map(d => {
if(d.isDatePunctual) {
const datePart = d.date;
return toJsDate(datePart);
} else {
console.log('birthday is complicated');
return null;
}
});
}
npm ls | grep -i type ├── @babel/preset-typescript@7.17.12 ├── @fortawesome/fontawesome-common-types@0.3.0 ├── @types/alpinejs@3.7.0 ├── @types/isomorphic-fetch@0.0.36 ├── @types/jest@26.0.24 ├── @types/node@10.17.60 ├── typescript@4.7.4
0.3.1
is the right version; but I should have mentioned that you must import toJsDate
in order to use it:
import { readGedcom, toJsDate } from 'read-gedcom';
(or if you are transpiling to CJS:)
const { readGedcom, toJsDate } = require('read-gedcom');
The final code ended up being
import { readGedcom, toJsDate, ValueDatePunctual } from 'read-gedcom';
this.myBirthday = g.getIndividualRecord(`${this.myGedId}`)
.getEventBirth()
.getDate()
.valueAsDate()
.map(d => {
if(d && d.isDatePunctual) {
const datePart = (d as ValueDatePunctual).date;
return toJsDate(datePart);
} else {
return null;
}
});
thanks for your help!!!
Great! You're welcome.
This d as ValueDatePunctual
appears unnecessary to me; in fact the library is designed to avoid type ascriptions at all costs. Here isDatePunctual === true
implies date !== undefined
and the compiler should be able to pick that up. In fact I just tested it locally without the ascription, so you should be able to remove it in your code too.
Anyway don't hesitate if you have more questions. I am striving to make this library better, and feedback/suggestions/contributions are welcome.
it is probably a function of my tsconfig, as I have noticed that npm run build is far more strict than the hugo transpiler,
cat tsconfig.json
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"lib": ["ES2020", "DOM"],
"moduleResolution": "Node",
"experimentalDecorators": true,
"declaration": true,
"useDefineForClassFields": false,
"strict": true,
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"noEmit": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noImplicitReturns": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"alwaysStrict": true,
"noFallthroughCasesInSwitch": false,
"strictPropertyInitialization": false,
"typeRoots": [
"./node_modules/@types"
]
},
"exclude": [
"node_modules",
"cdk.out",
"infrastructure/cdk.out"
]
}
I see, thanks. With this config the example I provided does not compile because the option strictNullChecks
is enabled (I have forgotten a null check), but the said type ascription is still optional.
In my opinion it's a good thing to leave this option on, I should enable it on this repo too.
In the API docs, I see the toJsDate function, but I am having trouble understanding how to call it. Can you add an example on extracting when an event occurred from a gedcom file, and reformatting to match the (for example) the user's locale for display?