Skip to content

Commit e96e240

Browse files
authored
Merge pull request #35 from codingtools/feature/date-utility
Feature/date utility basic functionality
2 parents 864964c + 39300ef commit e96e240

File tree

5 files changed

+202
-2
lines changed

5 files changed

+202
-2
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ USAGE
4949
* [`cdt autocomplete [SHELL]`](#cdt-autocomplete-shell)
5050
* [`cdt bundlephobia [PACKAGE]`](#cdt-bundlephobia-package)
5151
* [`cdt crypto [STRING]`](#cdt-crypto-string)
52+
* [`cdt datetime [DATE]`](#cdt-datetime-date)
5253
* [`cdt hash [STRING]`](#cdt-hash-string)
5354
* [`cdt help [COMMAND]`](#cdt-help-command)
5455
* [`cdt minify [FILE]`](#cdt-minify-file)
@@ -112,6 +113,24 @@ OPTIONS
112113

113114
_See code: [src/commands/crypto.ts](https://github.com/codingtools/cdt/blob/v0.1.4/src/commands/crypto.ts)_
114115

116+
## `cdt datetime [DATE]`
117+
118+
Date and Time utility
119+
120+
```
121+
USAGE
122+
$ cdt datetime [DATE]
123+
124+
OPTIONS
125+
-d, --date=date Datetime input string, could also be passed through argument
126+
-f, --format=format Datetime format
127+
-h, --help show CLI help
128+
-l, --locale=locale Locale, default: en
129+
-z, --timezone=timezone Timezone for Datetime
130+
```
131+
132+
_See code: [src/commands/datetime.ts](https://github.com/codingtools/cdt/blob/v0.1.4/src/commands/datetime.ts)_
133+
115134
## `cdt hash [STRING]`
116135

117136
Hashing functionality for a string/file

package-lock.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
"@oclif/plugin-help": "^2.2.1",
1717
"@oclif/plugin-not-found": "^1.2.3",
1818
"@oclif/plugin-warn-if-update-available": "^1.7.0",
19-
"@types/crypto-js": "^3.1.43",
20-
"@types/signale": "^1.2.1",
2119
"axios": "^0.19.0",
2220
"chalk": "^2.4.2",
2321
"crypto-js": "^3.1.9-1",
2422
"jshashes": "^1.0.7",
2523
"minify": "^4.1.3",
24+
"moment": "^2.24.0",
25+
"moment-timezone": "^0.5.27",
2626
"nyc": "^14.1.1",
2727
"ora": "^4.0.2",
2828
"signale": "^1.4.0",
@@ -34,7 +34,10 @@
3434
"@oclif/tslint": "^3.1.1",
3535
"@types/chai": "^4.2.3",
3636
"@types/mocha": "^5.2.7",
37+
"@types/moment-timezone": "^0.5.12",
3738
"@types/node": "^12.11.2",
39+
"@types/crypto-js": "^3.1.43",
40+
"@types/signale": "^1.2.1",
3841
"chai": "^4.2.0",
3942
"globby": "^10.0.1",
4043
"mocha": "^6.2.2",
@@ -61,6 +64,9 @@
6164
"oclif": {
6265
"commands": "./lib/commands",
6366
"bin": "cdt",
67+
"macos": {
68+
"identifier": "@codingtools/cdt"
69+
},
6470
"plugins": [
6571
"@oclif/plugin-help",
6672
"@oclif/plugin-not-found",

src/commands/datetime.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import {Command, flags} from '@oclif/command'
2+
import chalk from 'chalk'
3+
import * as moment from 'moment-timezone' //has both momentjs and timezone support
4+
5+
// @ts-ignore
6+
moment.suppressDeprecationWarnings = true
7+
8+
import Logger from '../utilities/logger'
9+
10+
// TODO: add timezone support for input and output
11+
export default class Datetime extends Command {
12+
static description = 'Date and Time utility'
13+
14+
static defaultFormat = 'Do MMMM YYYY, h:m:s A, Z UTC'
15+
16+
static flags = {
17+
help: flags.help({char: 'h'}),
18+
date: flags.string({char: 'd', description: 'Datetime input string, default: Current Datetime, could also be passed through argument'}),
19+
format: flags.string({char: 'f', description: `Datetime format, default: ${Datetime.defaultFormat}`}),
20+
timezone: flags.string({char: 'z', description: 'Timezone for Datetime parsing, default: Your timezone'}),
21+
locale: flags.string({char: 'l', description: 'Locale, default: en'}),
22+
}
23+
24+
static args = [{name: 'date'}]
25+
26+
//arguments 'date' ( default now() ), 'format' ( default 'dd-MMM-YYYY' ), 'timezone' (default user local)
27+
async run() {
28+
const {args, flags} = this.parse(Datetime)
29+
30+
args.date = this.getDateString(flags, args) // getting date object
31+
args.locale = this.getLocale(flags, args) // getting date object
32+
args.format = this.getFormat(flags, args) // getting date object
33+
args.timezone = this.getTimezone(flags, args) // getting date object
34+
35+
Logger.info(this, `Input String: ${ args.date ? args.date : chalk.magenta('Not Provided, using Current timestamp') }`)
36+
Logger.info(this, `Locale: ${chalk.magenta(args.locale)}`)
37+
Logger.info(this, `Format: ${chalk.magenta(args.format)}`)
38+
Logger.info(this, `Timezone: ${chalk.magenta(args.timezone)}`) // true - do not used cached timezone, find every time
39+
40+
args.momentDate = this.getMomentDate(flags, args)
41+
this.checkParameters(flags, args)
42+
43+
Logger.success(this, `${args.momentDate.tz(args.timezone).format(args.format)}`)
44+
45+
}
46+
47+
// tslint:disable-next-line:no-unused
48+
private getTimezone(flags: any, args: any) {
49+
if (flags.timezone)
50+
return flags.timezone
51+
else
52+
return moment.tz.guess(true)
53+
}
54+
55+
// tslint:disable-next-line:no-unused
56+
private getLocale(flags: any, args: any) {
57+
if (flags.locale)
58+
return flags.locale
59+
else
60+
return 'en'
61+
}
62+
63+
private getDateString(flags: any, args: any) {
64+
let dateString: string | undefined
65+
66+
if (args.date)
67+
dateString = args.date
68+
else if (flags.date)
69+
dateString = flags.date
70+
else
71+
dateString = undefined // will be set to now()
72+
73+
return dateString
74+
}
75+
76+
private getMomentDate(flags: any, args: any) {
77+
let date: moment.Moment
78+
79+
if (args.date)
80+
date = moment.tz(args.date, args.timezone)
81+
else
82+
date = moment.tz([], args.timezone) // return now() if args.date is undefined
83+
84+
// set locale
85+
date.locale(flags.locale)
86+
return date
87+
}
88+
89+
// tslint:disable-next-line:no-unused
90+
private checkParameters(flags: any, args: any) {
91+
if (!args.momentDate.isValid())
92+
Logger.error(this, 'Invalid Date String Passed')
93+
}
94+
95+
// tslint:disable-next-line:no-unused
96+
private getFormat(flags: any, args: any) {
97+
return flags.format ? flags.format : Datetime.defaultFormat
98+
}
99+
}

test/commands/datetime.test.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import {expect, test} from '@oclif/test'
2+
import * as moment from 'moment-timezone' //has both momentjs and timezone support
3+
4+
describe('datetime', () => {
5+
test
6+
.stdout()
7+
.command(['datetime', '2019-07-01 00:00:00'])
8+
.it('If locale is not given, default - en', ctx => {
9+
expect(ctx.stdout).to.contain(`1st July 2019, 12:0:0 AM, ${moment('01-Jul-2019').format('Z')} UTC`)
10+
})
11+
12+
test
13+
.stdout()
14+
.command(['datetime', '2019-07-01 00:00:00', '-l', 'fr'])
15+
.it('If locale is given for french', ctx => {
16+
expect(ctx.stdout).to.contain(`1er juillet 2019, 12:0:0 AM, ${moment('01-Jul-2019').format('Z')} UTC`)
17+
})
18+
19+
20+
// test for hindi commented because of Timezone runtime
21+
// test
22+
// .stdout()
23+
// .command(['datetime', '2019-07-01 00:00:00', '-l', 'hi'])
24+
// .it('If locale is given for hindi', ctx => {
25+
// expect(ctx.stdout).to.contain('१ जुलाई २०१९, १२:०:० रात, +०५:३० UTC')
26+
// })
27+
28+
test
29+
.stdout()
30+
.command(['datetime', 'not a real date'])
31+
.exit(0)
32+
.it('Invalid Datetime or Datetime format with args', ctx => {
33+
expect(ctx.stdout).to.contain('Invalid Date String Passed')
34+
})
35+
36+
test
37+
.stdout()
38+
.command(['datetime', '-d', 'not a real date'])
39+
.exit(0)
40+
.it('Invalid Datetime or Datetime format with flags', ctx => {
41+
expect(ctx.stdout).to.contain('Invalid Date String Passed')
42+
})
43+
44+
test
45+
.stdout()
46+
.command(['datetime', '20190501', '-f', 'DD-MM-YYYY'])
47+
.it('Format Date with a valid Format', ctx => {
48+
expect(ctx.stdout).to.contain('01-05-2019')
49+
})
50+
51+
test
52+
.stdout()
53+
.command(['datetime', '201901d'])
54+
.exit(0)
55+
.it('Invalid Date passed', ctx => {
56+
expect(ctx.stdout).to.contain('Invalid Date String Passed')
57+
})
58+
59+
})

0 commit comments

Comments
 (0)