diff --git a/.coveralls.yml b/.coveralls.yml deleted file mode 100644 index cf27a37..0000000 --- a/.coveralls.yml +++ /dev/null @@ -1 +0,0 @@ -service_name: travis-pro diff --git a/.denolint.json b/.denolint.json new file mode 100644 index 0000000..2f905d1 --- /dev/null +++ b/.denolint.json @@ -0,0 +1,5 @@ +{ + "rules": { + "tags": ["recommended"] + } +} diff --git a/.eslintrc.yml b/.eslintrc.yml deleted file mode 100644 index eab45db..0000000 --- a/.eslintrc.yml +++ /dev/null @@ -1 +0,0 @@ -extends: standard diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..672292c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,46 @@ +name: Test or Release + +on: + - push + - pull_request + +jobs: + test-or-release: + runs-on: ubuntu-latest + steps: + - name: Checkout Sources + uses: actions/checkout@v2 + - name: Install Node + uses: actions/setup-node@v2 + with: + node-version: 'lts/*' + registry-url: 'https://registry.npmjs.org' + - name: Install PNPM + uses: pnpm/action-setup@v2 + with: + version: '>=6' + run_install: | + - args: [--frozen-lockfile, --no-verify-store-integrity] + - name: Test + run: npm test + - name: Examples + run: | + cd examples/nodejs + pnpm i --frozen-lockfile --no-verify-store-integrity + npm test + cd ../browser-separate + pnpm i --frozen-lockfile --no-verify-store-integrity + npm test + cd ../browser-bundled + pnpm i --frozen-lockfile --no-verify-store-integrity + npm test + - name: Coverage + uses: codecov/codecov-action@v2 + - name: Publish + uses: cycjimmy/semantic-release-action@v2 + with: + semantic_version: 18 + branches: master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 43e38f7..2f61648 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ src/lookup/data*.js src/index-*.d.ts src/lookup/data-*.d.ts test/browser -test/typings.test.js +test/types.test.js diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 69f9028..0000000 --- a/.npmignore +++ /dev/null @@ -1,10 +0,0 @@ -.DS_Store -.editorconfig -.gitignore -.npmignore -.vscode -examples -perf -rollup.config.js -test -util diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b0dd81c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -sudo: false -language: node_js -cache: - directories: - - ~/.npm -notifications: - email: false -node_js: - - '12' - - '10' - - '8' -before_install: - - npm i -g npm -after_success: - - test `node --version | cut -c 2` -eq 8 && npm run coverage - - npx semantic-release -branches: - except: - - /^v\d+\.\d+\.\d+$/ diff --git a/.vscode/settings.json b/.vscode/settings.json index d6dfc8c..9c0752c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,6 +6,7 @@ "search.exclude": { "**/src/lookup/data*.js": true, "**/dist/**": true, + "**/out/**": true, "**/test/browser/**": true, "**/test/typings.test.js": true } diff --git a/README.md b/README.md index 908e65b..8ec0638 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,19 @@ # Time Zone Support -[![NPM version](https://badge.fury.io/js/timezone-support.png)](http://badge.fury.io/js/timezone-support) -[![Build Status](https://travis-ci.org/prantlf/timezone-support.png)](https://travis-ci.org/prantlf/timezone-support) -[![Coverage Status](https://coveralls.io/repos/github/prantlf/timezone-support/badge.svg?branch=master)](https://coveralls.io/github/prantlf/timezone-support?branch=master) + +[![Latest version](https://img.shields.io/npm/v/timezone-support) + ![Dependency status](https://img.shields.io/librariesio/release/npm/timezone-support) +](https://www.npmjs.com/package/timezone-support) +[![Coverage](https://codecov.io/gh/prantlf/timezone-support/branch/master/graph/badge.svg)](https://codecov.io/gh/prantlf/timezone-support) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/9f1034029c0747a980cd49f64f16338b)](https://www.codacy.com/app/prantlf/timezone-support?utm_source=github.com&utm_medium=referral&utm_content=prantlf/timezone-support&utm_campaign=Badge_Grade) -[![Dependency Status](https://david-dm.org/prantlf/timezone-support.svg)](https://david-dm.org/prantlf/timezone-support) -[![devDependency Status](https://david-dm.org/prantlf/timezone-support/dev-status.svg)](https://david-dm.org/prantlf/timezone-support#info=devDependencies) -[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) -[![NPM Downloads](https://nodei.co/npm/timezone-support.png?downloads=true&stars=true)](https://www.npmjs.com/package/timezone-support) Lightweight time zone listing and date converting. Intended for adding time zone support to high-level date libraries, but also for direct application usage. * Tiny code base - 4.6 KB minified, 1.7 KB gzipped. Do not pack unnecessary weight in your application. * Packed time zone data - 924 KB minified, 33.6 KB gzipped. Single time zones are unpacked on demand. * Smaller bundles of code with limited data - 1900-2050 (206 kB minified, 25.4 kB gzipped), 1970-2038 (141 kB minified, 15.8 kB gzipped) and 2012-2022 (31.3 KB minified, 8.25 kB gzipped). -* Generated from the official time zone database version 2019a. Canonical time zone names, aliases, UTC offsets, and daylight-saving time changes. +* Generated from the official time zone database version 2022f. Canonical time zone names, aliases, UTC offsets, and daylight-saving time changes. +* ESM, UMD and CJS module formats provided. * Minimal interface for time zone lookup and conversions. Parsing, formatting and manipulating dates is usually the task for a higher-level date library. **Attention**: exported identifiers in vanilla browser modules changed in the version 2.0.0. See the [migration guide] for more information. @@ -56,13 +55,11 @@ const nativeDate = new Date(getUnixTime(berlinTime, berlin)) ## Installation and Getting Started -This module can be installed in your project using [NPM] or [Yarn]. Make sure, that you use [Node.js] version 6 or newer. - -```sh -$ npm i timezone-support --save -``` +This module can be installed in your project using [NPM], [PNPM] or [Yarn]. Make sure, that you use [Node.js] version 14.8 or newer. ```sh +$ npm i timezone-support +$ pnpm i timezone-support $ yarn add timezone-support ``` @@ -72,7 +69,7 @@ Functions are exposed as named exports from the package modules, for example: const { findTimeZone, getZonedTime } = require('timezone-support') ``` -You can read more about the [module loading](./docs/API.md#loading) in other environments, like with ES6 or in web browsers. [Usage scenarios](./docs/usage.md#usage-scenarios) demonstrate applications of this library in typical real-world scenarios. [Design concepts](./docs/design.md#design-concepts) explain the approach to time zone handling taken by tni library and types of values used ion the interface. [Generating custom time zone data](./docs/usage.md#generate-custom-time-zone-data) will allow you to save the overall package size by limiting the supported year span. Finally, the [API reference](./docs/API.md#api-reference) lists all functions with a description of their functionality. +You can read more about the [module loading] in other environments, like with ES6 or in web browsers. [Usage scenarios] demonstrate applications of this library in typical real-world scenarios. [Design concepts] explain the approach to time zone handling taken by tni library and types of values used ion the interface. [Generating custom time zone data] will allow you to save the overall package size by limiting the supported year span. Finally, the [API reference] lists all functions with a description of their functionality. You can see [complete sample applications] too, which can help you start with integration of this library. @@ -85,34 +82,24 @@ You can see [complete sample applications] too, which can help you start with in In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using Grunt. -## Release History - -* 2018-06-11 v2.0.2 Upgrade the time zone database to the version 2019a. -* 2018-06-11 v2.0.1 Default to midnight, if the time part of a date is missing. -* 2018-06-10 v2.0.0 Use proper identifiers in vanilla browser modules. -* 2018-11-17 v1.8.0 Include time zone data for years 1970-2038. -* 2018-11-17 v1.7.0 Include full time zone data separately loadable. -* 2018-11-06 v1.6.0 Upgrade the time zone database to the version 2018g. -* 2018-10-08 v1.5.5 Fix compatibility with IE. Thanks, [Andrii](https://github.com/AndriiDidkivsky)! -* 2018-10-06 v1.5.0 Add TypeScript export declarations. -* 2018-09-30 v1.4.0 Add limited data for just the current decade - years 2012-2022. -* 2018-09-18 v1.3.0 Maintain the property dayOfWeek in the time object. -* 2018-09-16 v1.2.0 Add a new getUTCOffset method for more lightweight integrations. -* 2018-09-03 v1.1.0 Set the property epoch to the time object. -* 2018-09-02 v1.0.0 Initial release - ## License -Copyright (c) 2018-2019 Ferdinand Prantl +Copyright (c) 2018-2022 Ferdinand Prantl Licensed under the MIT license. [Node.js]: http://nodejs.org/ [NPM]: https://www.npmjs.com/ -[RequireJS]: https://requirejs.org/ +[PNPM]: https://pnpm.io/ +[Yarn]: https://yarnpkg.com/ [Day.js]: https://github.com/iamkun/dayjs [date-fns]: https://github.com/date-fns/date-fns [timeZone plugin]: https://github.com/prantlf/dayjs/blob/combined/docs/en/Plugin.md#timezone [date-fns-timezone]: https://github.com/prantlf/date-fns-timezone [migration guide]: docs/migration.md#migration-from-1x-to-2x [complete sample applications]: examples#readme +[module loading]: ./docs/API.md#loading +[Usage scenarios]: ./docs/usage.md#usage-scenarios +[Design concepts]: ./docs/design.md#design-concepts +[Generating custom time zone data]: ./docs/usage.md#generate-custom-time-zone-data +[API reference]: ./docs/API.md#api-reference diff --git a/bin/create-timezone-data b/bin/create-timezone-data deleted file mode 100755 index 5019b60..0000000 --- a/bin/create-timezone-data +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env node - -'use strict' - -const commander = require('commander') -const { createTimeZoneData } = require('../util/data-creator') -const pkg = require('../package.json') - -commander.version(pkg.version) - .description('Generates time zone data for a selected year range.') - .usage('[options] ') - .option('-a, --all-years', 'includes all available years') - .option('-c, --as-cjs-module', 'format the time zone data as a CommonJS module') - .option('-d, --as-amd-module', 'format the time zone data as an AMD module') - .option('-m, --as-module', 'format the time zone data as a JavaScript module') - .option('-n, --umd-name ', 'UMD global export name, if not "timezoneData"') - .option('-o, --output-file ', 'write the time zone data to a file') - .option('-u, --as-umd-module', 'format the time zone data as an UMD module') - .option('-o, --output-file ', 'write the time zone data to a file') - -commander.on('--help', function () { - console.log() - console.log(' Time zone data are printed on the standard output as JSON by default.') - console.log() - console.log(' Examples:') - console.log() - console.log(' $ create-timezone-data 2012 2022') - console.log(' $ create-timezone-data -m -o custom-data.js 1970 2038') -}) - -commander.parse(process.argv) -const [ firstYear, lastYear ] = commander.args -if (!(firstYear && lastYear) && !commander.allYears) { - commander.help() -} - -const { - asModule, asCjsModule, asAmdModule, asUmdModule, umdName, outputFile -} = commander -createTimeZoneData({ - firstYear, - lastYear, - asModule, - asCjsModule, - asAmdModule, - asUmdModule, - umdName, - outputFile -}) - .then(timeZoneData => { - if (!outputFile) { - console.log(timeZoneData) - } - }) - .catch(error => { - console.error(error.message) - process.exitCode = 1 - }) diff --git a/bin/create-timezone-data.js b/bin/create-timezone-data.js new file mode 100755 index 0000000..402fdec --- /dev/null +++ b/bin/create-timezone-data.js @@ -0,0 +1,102 @@ +#!/usr/bin/env node + +const { createTimeZoneData } = require('../util/data-creator') + +function help() { + console.log(`Generates time zone data for a selected year range. + +Usage: create-timezone-data [options] + +Options: + -a|--all-years includes all available years + -c|--as-cjs-module format the time zone data as a CommonJS module + -d|--as-amd-module format the time zone data as an AMD module + -m|--as-module format the time zone data as a JavaScript module + -n|--umd-name UMD global export name, if not "timezoneData" + -o|--output-file write the time zone data to a file + -u|--as-umd-module format the time zone data as an UMD module + -V|--version print version number + -h|--help print usage instructions + + Time zone data are printed on the standard output as JSON by default. + +Examples: + $ create-timezone-data 2012 2022 + $ create-timezone-data -m -o custom-data.js 1970 2038`) + process.exit(0) +} + +const { argv } = process +const args = [] +let allYears, asModule, asCjsModule, asAmdModule, asUmdModule, umdName, outputFile + +for (let i = 2, l = argv.length; i < l; ++i) { + const arg = argv[i] + const match = /^(-|--)(no-)?([a-zA-Z][-a-zA-Z]*)(?:=(.*))?$/.exec(arg) + if (match) { + const parseArg = (arg, flag) => { + switch (arg) { + case 'a': case 'all-years': + allYears = flag + return + case 'c': case 'as-cjs-module': + asCjsModule = flag + return + case 'd': case 'as-amd-module': + asAmdModule = flag + return + case 'm': case 'as-module': + asModule = flag + return + case 'n': case 'umd-name': + umdName = match[4] || argv[++i] + return + case 'o': case 'output-file': + outputFile = match[4] || argv[++i] + return + case 'u': case 'as-umd-module': + recursive = flag + return + case 'V': case 'version': + console.log(require('../package.json').version) + process.exit(0) + break + case 'h': case 'help': + help() + } + console.error(`unknown option: "${arg}"`) + process.exit(1) + } + if (match[1] === '-') { + const flags = match[3].split('') + for (const flag of flags) parseArg(flag, true) + } else { + parseArg(match[3], match[2] !== 'no-') + } + continue + } + args.push(arg) +} + +const [ firstYear, lastYear ] = args +if (!(firstYear && lastYear) && !allYears) help() + +createTimeZoneData({ + firstYear, + lastYear, + asModule, + asCjsModule, + asAmdModule, + asUmdModule, + umdName, + outputFile +}) +.then(timeZoneData => { + if (!outputFile) { + console.log(timeZoneData) + } +}) +.catch(error => { + console.error(error.message) + process.exitCode = 1 +}) diff --git a/docs/API.md b/docs/API.md index 9a13fb4..b818b98 100644 --- a/docs/API.md +++ b/docs/API.md @@ -34,9 +34,7 @@ const { findTimeZone, getZonedTime } = require('timezone-support') Load the main module in an application using ES6 modules: ```js -import { - findTimeZone, getZonedTime -} from './node_modules/timezone-support/src/index.js' +import { findTimeZone, getZonedTime } from 'timezone-support' ``` Load the main module in the browser with plain JavaScript: @@ -50,11 +48,19 @@ Load the main module in the browser with plain JavaScript: ``` -You can also load a specific version from CDN, for example: https://unpkg.com/timezone-support@2.0.2/dist/index.umd.js. +You can also load a specific version from CDN, for example: https://unpkg.com/timezone-support@3.0.0/dist/index.umd.js. + +Load the main module in Node.js older than 14.8, which didn't support `exports` in `package.json`: + +```js +import { + findTimeZone, getZonedTime +} from './node_modules/timezone-support/dist/index.mjs' +``` ## Modules -Modules in the `src` directory require ES6 including the new module syntax, as available in Node.js 8 and newer. Modules in the `dist` directory require ES5 and follow the CommonJS standard for older Node.js releases. Files `dist/*.umd.js` require ES5, are minified and follow the UMD standard to work well in web browsers. +Modules `dist/*.mjs` require ES6 including the new module syntax, as available in Node.js 8 and newer. Modules `dist/*.js` require ES5 and follow the CommonJS standard for older Node.js releases. Files `dist/*.umd.js` require ES5, are minified and follow the UMD standard to work well in web browsers. ### index @@ -62,30 +68,48 @@ Main package module. The most usually chosen module with time zone lookup and da ``` const { ... } = require('timezone-support') -import { ... } from './node_modules/timezone-support/src/index.js' +import { ... } from 'timezone-support' ``` +Importing in Node.js older than 14.8, which didn't support `exports` in `package.json`: + +``` +import { ... } from './node_modules/timezone-support/dist/index.mjs' +``` + ### lookup-convert Offers the time zone lookup and date conversion functionality, like the `index` module, but does not include the time zone data. You have to initialize the library with your own the time zone data by calling [populateTimeZones](#populatetimezones) before the first usage. ``` const { ... } = require('timezone-support/dist/lookup-convert') -import { ... } from './node_modules/timezone-support/src/lookup-convert.js' +import { ... } from 'timezone-support/lookup-convert' ``` +Importing in Node.js older than 14.8, which didn't support `exports` in `package.json`: + +``` +import { ... } from './node_modules/timezone-support/dist/lookup-convert.mjs' +``` + ### parse-format Offers a minimal date parsing and formatting support, if you want to use this library in an end-user application. Recognizes only numeric formatting tokens and no locale support. ``` const { ... } = require('timezone-support/dist/parse-format') -import { ... } from './node_modules/timezone-support/src/parse-format.js' +import { ... } from 'timezone-support/parse-format' ``` +Importing in Node.js older than 14.8, which didn't support `exports` in `package.json`: + +``` +import { ... } from './node_modules/timezone-support/dist/parse-format.mjs' +``` + ## Functions Functions converting to an arbitrary time zone accept either a `Date` object, or a UNIX timestamp. (The UNIX timestamp is the time from the epoch in milliseconds, as returned by `date.prototype.getTime`.) They produce a complete [time object]. Functions converting from an arbitrary time zone accept a [time object] and return the UNIX timestamp. @@ -156,7 +180,7 @@ formatZonedTime(time: Time, format: string) : string Formats a [time object] using a custom format pattern to a string. ```js -const { formatZonedTime } = require('timezone-support/dist/parse-format') +const { formatZonedTime } = require('timezone-support/parse-format') const time = { year: 2018, month: 9, day: 2, hours: 10, minutes: 0, zone: { abbreviation: 'CEST', offset: -120 } } @@ -293,7 +317,7 @@ parseZonedTime(input: string, format: string) : Time Parses a date string using a custom format pattern to a [time object]. If the string does not contain a time zone offset, it can be added by [setTimeZone](#settimezone). ```js -const { parseZonedTime } = require('timezone-support/dist/parse-format') +const { parseZonedTime } = require('timezone-support/parse-format') const input = '2.9.2018 10:00 CEST+02:00' const format = 'D.M.YYYY H:mm zZ' @@ -354,15 +378,15 @@ const data = { } ``` -See the [moment-timezone's latest data](../util/data/packed.json) as an example of the full data, which you can take a smaller part of to your application. This library includes [limited data for this decade](http://unpkg.com/timezone-support/dist/data-2012-2022.js) and [two other year spans](../src/lookup/). Read also abot [generation of custom time zone data](./usage.md#generate-custom-time-zone-data), which allows production of a module with smaller, limited time zone data for other time periods. +See the [moment-timezone's latest data](../util/data/packed.json) as an example of the full data, which you can take a smaller part of to your application. This library includes [limited data for this decade](http://unpkg.com/timezone-support@3.0.0/dist/data-2012-2022.js) and [two other year spans](../src/lookup/). Read also abot [generation of custom time zone data](./usage.md#generate-custom-time-zone-data), which allows production of a module with smaller, limited time zone data for other time periods. If this function is called later, than during the application startup, the behaviour of this module may be unpredictable. Some time zone data might be used and cached in the application. You should avoid re-initialization to prevent hidden errors. This function is not exported from the `index` module to prevent usage mistakes, because that module includes the complete time zone data already. ```js -const { populateTimeZones, findTimeZone, getZonedTime } = require('timezone-support/dist/lookup-convert') -const data = require('timezone-support/dist/data-2012-2022') +const { populateTimeZones, findTimeZone, getZonedTime } = require('timezone-support/lookup-convert') +const data = require('timezone-support/data-2012-2022') // Get the time zone support ready to handle dates from years 2012-2022. populateTimeZones(data) diff --git a/docs/design.md b/docs/design.md index 798788d..b62a905 100644 --- a/docs/design.md +++ b/docs/design.md @@ -4,7 +4,7 @@ The purpose of this library is to offer an efficient support for time zone handl * Lightweight - nothing else is included. Thus serving well for other date & time libraries, but also for applications, which do not manipulate dates. * Tiny - use packed time zone data, unpacked on demand. Compromise between loading time and being ready to use immediately. -* Reliable - generated from the fresh official time zone database version 2019a. Canonical time zone names, aliases, UTC offsets, and daylight-saving time changes. +* Reliable - generated from the fresh official time zone database version 2022f. Canonical time zone names, aliases, UTC offsets, and daylight-saving time changes. * Customizable - named exports and functions divided to separate modules allow tree-shaking. Alternative time zone data can be supplied to reduce the library size. ### Table of Contents diff --git a/docs/usage.md b/docs/usage.md index d0b3b03..0e3b3a0 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -80,7 +80,7 @@ See the function [getUnixTime](./API.md#getunixtime) for more information. Some applications let their users freely configure, how dates will be formatted. While date formatting is usually supplied by higher-level libraries, which support locales and include other functionality to manipulate dates, very simple formatting is available in this library too. ```js -const { formatZonedTime } = require('timezone-support/dist/parse-format') +const { formatZonedTime } = require('timezone-support/parse-format') const zonedTime = { year: 2018, month: 9, day: 2, hours: 10, minutes: 0, zone: { abbreviation: 'CEST', offset: -120 } } @@ -94,7 +94,7 @@ See the function [formatZonedTime](./API.md#formatzonedtime) for more informatio Some applications let their users freely configure, what date format will be used when parsing strings. While string parsing is usually supplied by higher-level libraries, which support locales and include other functionality to manipulate dates, very simple parsing is available in this library too. ```js -const { parseZonedTime } = require('timezone-support/dist/parse-format') +const { parseZonedTime } = require('timezone-support/parse-format') const displayTime = '2.9.2018 10:00 CET+02:00' const zonedTime = parseZonedTime(displayTime, 'D.M.YYYY H:mm zZ') @@ -183,8 +183,8 @@ Data for 2012-2022: 27 KB minified, 6.5 KB gzipped Custom time zone data can be used if the module `lookup-convert` is loaded instead of the default `index` module. ```html - - + + + ``` -The following data modules ara published within this project: +The following data modules ara published within this project to be used in Node.js: + +```txt +timezone-support/data +timezone-support/data-1900-2050 +timezone-support/data-1970-2038 +timezone-support/data-2012-2022 +``` + +and in the browser: ```txt dist/data.umd.js @@ -223,7 +232,16 @@ dist/data-1970-2038.umd.js dist/data-2012-2022.umd.js ``` -The following complete (code+data) modules ara published within this project: +The following complete (code+data) modules ara published within this project to be used in Node.js: + +```txt +timezone-support/index +timezone-support/index-1900-2050 +timezone-support/index-1970-2038 +timezone-support/index-2012-2022 +``` + +and in the browser: ```txt dist/index.umd.js @@ -244,10 +262,10 @@ For example, you can generate time zone data for years 1978-2028 and save it to create-timezone-data -c -o custom-data-1978-2028.js 1978 2028 ``` -And then load them instead of the default full time zone data. You need to require `timezone-support/dist/lookup-convert` instead of `timezone-support` everywhere in your application and populate the library with the custom data, when your application starts: +And then load them instead of the default full time zone data. You need to require `timezone-support/lookup-convert` instead of `timezone-support` everywhere in your application and populate the library with the custom data, when your application starts: ```js -const { populateTimeZones } = require('timezone-support/dist/lookup-convert') +const { populateTimeZones } = require('timezone-support/lookup-convert') const data = require('./data-1978-2028') populateTimeZones(data) @@ -262,7 +280,7 @@ create-timezone-data -u -o custom-data-1978-2028.js -n timezoneData10782028 1978 And then load them at the beginning of a plain JavaScript application: ```html - + - + - + + diff --git a/test/browser.test.js b/test/browser.test.js index ee18d31..cb55e74 100644 --- a/test/browser.test.js +++ b/test/browser.test.js @@ -12,21 +12,7 @@ let server let browser let page -const customMatchers = { - toPass: function () { - return { - compare: function (result, message) { - return { - pass: result, - message: () => message - } - } - } - } -} - beforeAll(done => { - jasmine.addMatchers(customMatchers) server = connect() .use(serve(join(__dirname, '..'), { etag: false })) .listen(port, () => { @@ -53,7 +39,7 @@ afterAll(done => { }) const tests = readdirSync(join(__dirname, 'browser')) -for (let test of tests) { +for (const test of tests) { it(`Execute ${test}`, done => { let result page @@ -72,9 +58,8 @@ for (let test of tests) { return { summary, duration, results } }) }) - .then(({ summary, duration, results }) => { - expect(result).toPass(`${summary}; ${duration}\n${results}`) - done() - }) + .then(({ summary, duration, results }) => + expect(result).toPass(`${summary}; ${duration}\n${results}`)) + .finally(() => done()) }) } diff --git a/test/cjs.test.cjs b/test/cjs.test.cjs new file mode 100644 index 0000000..df8abf5 --- /dev/null +++ b/test/cjs.test.cjs @@ -0,0 +1,48 @@ +const { + listTimeZones, findTimeZone, getUTCOffset, getZonedTime, getUnixTime, + setTimeZone, convertTimeToDate, convertDateToTime +} = require('timezone-support') +const { populateTimeZones } = require('timezone-support/lookup-convert') +const { parseZonedTime, formatZonedTime } = require('timezone-support/parse-format') + +const timestamp = 1538822326765 +const date = new Date(timestamp) +const customDateString = '6.10.2018 12:38:46.765' +const customFormat = 'D.M.YYYY H:mm:ss.SSS' +const time = { + year: 2018, month: 10, day: 6, hours: 12, minutes: 38, seconds: 0 +} +const data = { + zones: [ + 'Europe/Berlin|CET CEST CEMT|-10 -20 -30|01010101010101210101210101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2aFe0 11d0 1iO0 11A0 1o00 11A0 Qrc0 6i00 WM0 1fA0 1cM0 1cM0 1cM0 kL0 Nc0 m10 WM0 1ao0 1cp0 dX0 jz0 Dd0 1io0 17c0 1fA0 1a00 1ehA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|41e5' + ], + links: [ + 'Europe/Berlin|Etc/Test' + ] +} + +listTimeZones() + +const berlin = findTimeZone('Europe/Berlin') + +getUTCOffset(date, berlin) +getUTCOffset(timestamp, berlin) + +const berlinTime = getZonedTime(date, berlin) +getZonedTime(timestamp, berlin) + +getUnixTime(time, berlin) +getUnixTime(berlinTime) + +setTimeZone(time, berlin) +setTimeZone(date, berlin, { useUTC: false }) + +convertTimeToDate(berlinTime) + +convertDateToTime(date) + +parseZonedTime(customDateString, customFormat) + +formatZonedTime(berlinTime, customFormat) + +populateTimeZones(data) diff --git a/test/esm.test.mjs b/test/esm.test.mjs new file mode 100644 index 0000000..73c3a40 --- /dev/null +++ b/test/esm.test.mjs @@ -0,0 +1,48 @@ +import { + listTimeZones, findTimeZone, getUTCOffset, getZonedTime, getUnixTime, + setTimeZone, convertTimeToDate, convertDateToTime +} from 'timezone-support' +import { populateTimeZones } from 'timezone-support/lookup-convert' +import { parseZonedTime, formatZonedTime } from 'timezone-support/parse-format' + +const timestamp = 1538822326765 +const date = new Date(timestamp) +const customDateString = '6.10.2018 12:38:46.765' +const customFormat = 'D.M.YYYY H:mm:ss.SSS' +const time = { + year: 2018, month: 10, day: 6, hours: 12, minutes: 38, seconds: 0 +} +const data = { + zones: [ + 'Europe/Berlin|CET CEST CEMT|-10 -20 -30|01010101010101210101210101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010|-2aFe0 11d0 1iO0 11A0 1o00 11A0 Qrc0 6i00 WM0 1fA0 1cM0 1cM0 1cM0 kL0 Nc0 m10 WM0 1ao0 1cp0 dX0 jz0 Dd0 1io0 17c0 1fA0 1a00 1ehA0 1a00 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00|41e5' + ], + links: [ + 'Europe/Berlin|Etc/Test' + ] +} + +listTimeZones() + +const berlin = findTimeZone('Europe/Berlin') + +getUTCOffset(date, berlin) +getUTCOffset(timestamp, berlin) + +const berlinTime = getZonedTime(date, berlin) +getZonedTime(timestamp, berlin) + +getUnixTime(time, berlin) +getUnixTime(berlinTime) + +setTimeZone(time, berlin) +setTimeZone(date, berlin, { useUTC: false }) + +convertTimeToDate(berlinTime) + +convertDateToTime(date) + +parseZonedTime(customDateString, customFormat) + +formatZonedTime(berlinTime, customFormat) + +populateTimeZones(data) diff --git a/test/setup-jest.js b/test/setup-jest.js new file mode 100644 index 0000000..a474bbb --- /dev/null +++ b/test/setup-jest.js @@ -0,0 +1,8 @@ +expect.extend({ + toPass(result, message) { + return { + pass: result, + message: () => message + } + } +}) diff --git a/test/typings.test.ts b/test/types.test.ts similarity index 91% rename from test/typings.test.ts rename to test/types.test.ts index 1217f03..f6fd12c 100644 --- a/test/typings.test.ts +++ b/test/types.test.ts @@ -1,6 +1,7 @@ import { - listTimeZones, findTimeZone, getUTCOffset, getZonedTime, getUnixTime, setTimeZone, convertTimeToDate, convertDateToTime -} from '..' + listTimeZones, findTimeZone, getUTCOffset, getZonedTime, getUnixTime, + setTimeZone, convertTimeToDate, convertDateToTime +} from 'timezone-support' import { populateTimeZones } from '../dist/lookup-convert' import { parseZonedTime, formatZonedTime } from '../dist/parse-format' @@ -21,17 +22,14 @@ test('Type declarations for TypeScript', () => { ] } - let berlin - let berlinTime - listTimeZones() - berlin = findTimeZone('Europe/Berlin') + const berlin = findTimeZone('Europe/Berlin') getUTCOffset(date, berlin) getUTCOffset(timestamp, berlin) - berlinTime = getZonedTime(date, berlin) + const berlinTime = getZonedTime(date, berlin) getZonedTime(timestamp, berlin) getUnixTime(time, berlin) diff --git a/tslint.yml b/tslint.yml deleted file mode 100644 index 79ad7e3..0000000 --- a/tslint.yml +++ /dev/null @@ -1 +0,0 @@ -extends: tslint-config-standard diff --git a/util/data-creator.js b/util/data-creator.js index c151fdc..31cefe9 100644 --- a/util/data-creator.js +++ b/util/data-creator.js @@ -1,5 +1,6 @@ -const { outputFile: writeFile } = require('fs-extra') -const tz = require('../node_modules/moment-timezone/moment-timezone-utils').tz +const { mkdir, writeFile } = require('fs/promises') +const { dirname } = require('path') +const tz = require('moment-timezone/moment-timezone-utils').tz const groupLeaders = require('./data/group-leaders.json') const unpackedTimeZoneData = require('./data/unpacked.json') const packedTimeZoneData = require('./data/packed.json') @@ -35,7 +36,7 @@ function formatUMDModule (content, umdName) { })))` } -function createTimeZoneData (options = {}) { +async function createTimeZoneData (options = {}) { const { asModule, asCjsModule, asAmdModule, asUmdModule, umdName, firstYear, lastYear, outputFile @@ -57,9 +58,11 @@ function createTimeZoneData (options = {}) { } else { console.log(`Writing all time zone data to "${outputFile}"...`) } - return writeFile(outputFile, content) + const outputDir = dirname(outputFile) + if (outputDir !== '.') await mkdir(outputDir, { recursive: true }) + await writeFile(outputFile, content) } - return Promise.resolve(content) + return content } exports.createTimeZoneData = createTimeZoneData diff --git a/util/generate-browser-tests.js b/util/generate-browser-tests.js index 4285394..72c26a2 100644 --- a/util/generate-browser-tests.js +++ b/util/generate-browser-tests.js @@ -1,25 +1,21 @@ -const { readFile, outputFile } = require('fs-extra') -const { promisify } = require('es6-promisify') +const { mkdir, readFile, rm, writeFile } = require('fs/promises') const { join } = require('path') const glob = require('fast-glob') -let rimraf = require('rimraf') - -rimraf = promisify(rimraf) const tests = join(__dirname, '../test') const browserTests = join(tests, 'browser') -const nonBrowserTests = ['browser.test.js', 'typings.test.js'] +const nonBrowserTests = ['browser.test.js', 'types.test.js'] const importFunctionsExpression = /import ({[^}]+}) from '..\/src\/([^']+)'/ const importDataExpression = /import (\w+) from '..\/src\/lookup\/([^']+)'/ function readTemplate () { console.log(`Reading browser test template...`) - return readFile(join(tests, 'browser.html'), { encoding: 'utf-8' }) + return readFile(join(tests, 'browser.html'), 'utf8') .then(template => template.split('\n')) } function readTest (file) { - return readFile(join(tests, file), { encoding: 'utf-8' }) + return readFile(join(tests, file), 'utf8') .then(content => { content = content.split('\n') return content.slice(2, content.length - 1) @@ -78,7 +74,8 @@ function formatPage (template, contentIndex, content) { console.log(`Deleting existing browser tests...`) let template -rimraf(browserTests) +rm(browserTests, { recursive: true, force: true }) + .then(() => mkdir(browserTests, { recursive: true })) .then(() => readTemplate()) .then(result => { template = result @@ -95,7 +92,7 @@ rimraf(browserTests) .then(content => { content = formatPage(template, scriptIndex, content) file = join(browserTests, file.substr(0, file.length - 2) + 'html') - return outputFile(file, content.join('\n')) + return writeFile(file, content.join('\n')) }) ) }, Promise.resolve())