Comparing version 1.3.0 to 1.4.0
@@ -10,2 +10,3 @@ "use strict"; | ||
const utils_1 = require("./utils"); | ||
const utils_2 = require("./utils"); | ||
/** Represents a DBF file. */ | ||
@@ -259,6 +260,20 @@ class DBFFile { | ||
break; | ||
case 'T': // DateTime | ||
if (buffer[offset] === 0x20) { | ||
value = null; | ||
break; | ||
} | ||
const julianDay = buffer.readInt32LE(offset); | ||
const msSinceMidnight = buffer.readInt32LE(offset + 4) + 1; | ||
value = utils_2.parseVfpDateTime({ julianDay, msSinceMidnight }); | ||
offset += 8; | ||
break; | ||
case 'D': // Date | ||
value = buffer[offset] === 0x20 ? null : utils_1.parseDate(substr(offset, 8, encoding)); | ||
value = buffer[offset] === 0x20 ? null : utils_2.parse8CharDate(substr(offset, 8, encoding)); | ||
offset += 8; | ||
break; | ||
case 'B': // Double | ||
value = buffer.readDoubleLE(offset); | ||
offset += field.size; | ||
break; | ||
case 'I': // Integer | ||
@@ -389,7 +404,17 @@ value = buffer.readInt32LE(offset); | ||
break; | ||
case 'T': // DateTime | ||
const { julianDay, msSinceMidnight } = utils_2.formatVfpDateTime(value); | ||
buffer.writeInt32LE(julianDay, offset); | ||
buffer.writeInt32LE(msSinceMidnight, offset + 4); | ||
offset += 8; | ||
break; | ||
case 'D': // Date | ||
value = value ? utils_1.formatDate(value) : ' '; | ||
value = value ? utils_2.format8CharDate(value) : ' '; | ||
iconv.encode(value, encoding).copy(buffer, offset, 0, 8); | ||
offset += 8; | ||
break; | ||
case 'B': // Double | ||
buffer.writeDoubleLE(value, offset); | ||
offset += field.size; | ||
break; | ||
case 'I': // Integer | ||
@@ -396,0 +421,0 @@ buffer.writeInt32LE(value, offset); |
@@ -15,3 +15,3 @@ "use strict"; | ||
throw new Error('Type must be a single character'); | ||
if (['C', 'N', 'F', 'L', 'D', 'I', 'M'].indexOf(type) === -1) | ||
if (FieldTypes.indexOf(type) === -1) | ||
throw new Error(`Type '${type}' is not supported`); | ||
@@ -35,2 +35,6 @@ // size | ||
throw new Error('Invalid field size (must be 10)'); | ||
if (type === 'T' && size !== 8) | ||
throw new Error('Invalid field size (must be 8)'); | ||
if (type === 'B' && size !== 8) | ||
throw new Error('Invalid field size (must be 8)'); | ||
// decimalPlaces | ||
@@ -44,2 +48,3 @@ const maxDecimals = version === 0x8b ? 18 : 15; | ||
exports.validateFieldDescriptor = validateFieldDescriptor; | ||
const FieldTypes = ['C', 'N', 'F', 'L', 'D', 'I', 'M', 'T', 'B']; | ||
//# sourceMappingURL=field-descriptor.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
function isValidFileVersion(fileVersion) { | ||
return [0x03, 0x83, 0x8b].includes(fileVersion); | ||
return [0x03, 0x83, 0x8b, 0x30].includes(fileVersion); | ||
} | ||
exports.isValidFileVersion = isValidFileVersion; | ||
//# sourceMappingURL=file-version.js.map |
@@ -15,12 +15,49 @@ "use strict"; | ||
exports.write = util_1.promisify(fs.write); | ||
/** Parses an 8-character date string of the form 'YYYYMMDD' into a Date object. */ | ||
function parseDate(s) { | ||
/** Parses an 8-character date string of the form 'YYYYMMDD' into a UTC Date object. */ | ||
function parse8CharDate(s) { | ||
return new Date(`${s.slice(0, 4)}-${s.slice(4, 6)}-${s.slice(6, 8)}`); | ||
} | ||
exports.parseDate = parseDate; | ||
/** Formats the given date as a string, in 8-character 'YYYYMMDD' format. */ | ||
function formatDate(d) { | ||
exports.parse8CharDate = parse8CharDate; | ||
/** Formats the given Date object as a string, in 8-character 'YYYYMMDD' format. `d` is assumed to be in UTC. */ | ||
function format8CharDate(d) { | ||
return d.toISOString().slice(0, 10).replace(/-/g, ''); | ||
} | ||
exports.formatDate = formatDate; | ||
exports.format8CharDate = format8CharDate; | ||
/** Parses the given Visual FoxPro DateTime representation into a UTC Date object. */ | ||
function parseVfpDateTime(dt) { | ||
// Compute year/month/day | ||
const s1 = dt.julianDay + 68569; | ||
const n = Math.floor(4 * s1 / 146097); | ||
const s2 = s1 - Math.floor(((146097 * n) + 3) / 4); | ||
const i = Math.floor(4000 * (s2 + 1) / 1461001); | ||
const s3 = s2 - Math.floor(1461 * i / 4) + 31; | ||
const q = Math.floor(80 * s3 / 2447); | ||
const s4 = Math.floor(q / 11); | ||
const year = (100 * (n - 49)) + i + s4; | ||
const month = q + 2 - (12 * s4); | ||
const day = s3 - Math.floor(2447 * q / 80); | ||
// Compute hour/minute/second | ||
const secsSinceMidnight = Math.floor(dt.msSinceMidnight / 1000); | ||
const minsSinceMidnight = Math.floor(secsSinceMidnight / 60); | ||
const second = secsSinceMidnight % 60; | ||
const minute = minsSinceMidnight % 60; | ||
const hour = Math.floor(minsSinceMidnight / 60); | ||
return new Date(Date.UTC(year, month - 1, day, hour, minute, second)); | ||
} | ||
exports.parseVfpDateTime = parseVfpDateTime; | ||
/** Formats the given Date object as a Visual FoxPro DateTime representation. `d` is assumed to be in UTC. */ | ||
function formatVfpDateTime(d) { | ||
// Compute year/month/day | ||
const msPerDay = 86400000; | ||
const daysFromEpoch = Math.floor(d.getTime() / msPerDay); | ||
const julianDaysBeforeEpoch = 2440588; | ||
const julianDay = Math.floor(daysFromEpoch + julianDaysBeforeEpoch); | ||
// Compute milliseconds since midnight | ||
const hrs = d.getUTCHours(); | ||
const mins = d.getUTCMinutes(); | ||
const secs = d.getUTCSeconds(); | ||
const msSinceMidnight = (((hrs * 60 + mins) * 60) + secs) * 1000; | ||
return { julianDay, msSinceMidnight }; | ||
} | ||
exports.formatVfpDateTime = formatVfpDateTime; | ||
//# sourceMappingURL=utils.js.map |
@@ -8,1 +8,5 @@ For information about the dBase III (.dbf) file format, see: | ||
- https://docs.microsoft.com/en-us/previous-versions/visualstudio/foxpro/8599s21w(v=vs.80) | ||
- https://docs.microsoft.com/en-us/previous-versions/visualstudio/foxpro/st4a0s68(v=vs.80) | ||
For test files, see: | ||
- https://github.com/infused/dbf/tree/master/spec/fixtures |
{ | ||
"name": "dbffile", | ||
"version": "1.3.0", | ||
"description": "Read and write .dbf (dBase III) files in Node.js", | ||
"version": "1.4.0", | ||
"description": "Read and write .dbf (dBase III & Visual FoxPro) files in Node.js", | ||
"main": "dist/index.js", | ||
@@ -9,5 +9,7 @@ "typings": "dist/index.d.ts", | ||
"build": "tsc -p src && tsc -p test && ncp test/fixtures dist/test/fixtures", | ||
"build:watch": "tsc -w -p src & (ncp test/fixtures dist/test/fixtures && tsc -w -p test)", | ||
"clean": "rimraf dist/", | ||
"prepublish": "npm run self-ref && npm run build", | ||
"test": "mocha --timeout 999999 --colors ./dist/test", | ||
"test:watch": "npm run build:watch & npx mocha ./dist/test/ --watch", | ||
"self-ref": "node ./scripts/enable-self-reference" | ||
@@ -22,3 +24,5 @@ }, | ||
"dBase", | ||
"dBase III" | ||
"dBase III", | ||
"vfp", | ||
"Visual FoxPro" | ||
], | ||
@@ -25,0 +29,0 @@ "author": { |
@@ -0,0 +0,0 @@ # DBFFile |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
164832
641