Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Feat input timeformat #16584

Merged
merged 6 commits into from
Jun 12, 2018
Merged

Feat input timeformat #16584

merged 6 commits into from
Jun 12, 2018

Conversation

Narretz
Copy link
Contributor

@Narretz Narretz commented May 30, 2018

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Feature

What is the current behavior? (You can also link to an open issue here)
Browser differences when displaying input time and datetime-local

What is the new behavior (if this is a feature change)?
Option to adjust the format

Does this PR introduce a breaking change?
No

Please check if the PR fulfills these requirements

  • The commit message follows our guidelines
  • Fix/Feature: Docs have been added/updated
  • Fix/Feature: Tests have been added; existing tests pass

Other information:
Closes #10721
Closes #16510

There are two options:

timeFormatSeconds can be used to configure if seconds or milliseconds should be displayed in general.
timeStripEmptySeconds mimics the behavior of Chrome to hide the seconds completely if they are zero.

Sorry, something went wrong.


if (isTimeType && isString(ctrl.$options.getOption('timeSecondsFormat'))) {
targetFormat = format.replace('ss.sss', ctrl.$options.getOption('timeSecondsFormat'));
if (targetFormat[targetFormat.length - 1] === ':') {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is ugly but I couldn't be bothered to use a regex :D

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is ugly and would be simpler with:

targetFormat = targetFormat.replace(/:$/, '');

Copy link
Member

@gkalpak gkalpak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally LGTM.
I am not a big fun of the names tbh, though:

  • timeFormat: Not accurate, because the format does not apply to the whole time value.
  • timeSecondsFormat: Maybe confusing, because when I read "seconds" my mind goes to the two digits after minutes. But arguably, milliseconds are part of the "seconds". So, I can live with that 😁
  • timeStripEmptySeconds: Maybe confusing (see above). Also, what does "empty seconds" mean? (I know what it means, but only because I looked at the code 😁)

Question:
Why not expand formatting to minutes as well (e.g. strip "empty" minutes)? Was it an arbitrary decision? Is it to match the behavior of a popular browser?

* this is the timezone of the browser.
*
* The format of the displayed time can be adjusted with the
* {@link ng.directive:ngModelOptions#ngModelOptions-arguments ngModelOptions} `timeFormat` and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timeFormat --> timeSecondsFormat (?)

var formatted = $filter('date')(value, targetFormat, timezone);

if (isTimeType && ctrl.$options.getOption('timeStripEmptySeconds')) {
formatted = formatted.replace(/(:00)?(\.000)?$/, '');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Since you are not using the captured groups, it is better to use (?:...) (instead of (...)).

@@ -255,6 +255,10 @@ var inputType = {
* The timezone to be used to read/write the `Date` instance in the model can be defined using
* {@link ng.directive:ngModelOptions ngModelOptions}. By default, this is the timezone of the browser.
*
* The format of the displayed time can be adjusted with the
* {@link ng.directive:ngModelOptions#ngModelOptions-arguments ngModelOptions} `timeFormat` and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timeFormat --> timeSecondsFormat (?)

*
* ## Formatting the value of `time` and `datetime-local`
*
* With the options `timeFormat` and `timeStripEmptySeconds` it is possible to adjust the value
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timeFormat --> timeSecondsFormat (?)

.component('timeExample', {
templateUrl: 'timeExample.html',
controller: function() {
this.time = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be an object?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, but it's good practice ;)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disagrees, but not strongly enough to be bothered 😛

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(it is only good practice if you are working directly with the scope - in this case you already have an object on the scope $ctrl so it doesn't matter)


this.optionChange = function() {
this.timeForm.timeFormatted.$overrideModelOptions(this.options);
this.time.value = new Date(this.time.value.getTime());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getTime() is redundant.

@@ -465,6 +527,21 @@ defaultModelOptions = new ModelOptions({
* Note that changing the timezone will have no effect on the current date, and is only applied after
* the next input / model change.
*
* - `timeFormat`: Defines if the `time` and `datetime-local` types should show seconds and
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timeFormat --> timeSecondsFormat (?)

* milliseconds. The option follows the format string of {@link date date filter}.
* By default, the options is `undefined` which is equal to
* `HH:mm:ss.sss` (shows hours, minutes, seconds and milliseconds). The other options are
* `HH:mm:ss` (strips milliseconds), and `HH:mm`, which strips both seconds and milliseconds.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This description seems out-of-date.

$rootScope.time = new Date(1970, 0, 1, 15, 41, 50, 50);
});
expect(inputElm.val()).toBe('1970-01-01T15:41:50.050');

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary empty line 😱

$rootScope.time = new Date(1970, 0, 1, 15, 41, 50, 50);
});
expect(inputElm.val()).toBe('15:41:50.050');

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary empty line 😱

@Narretz
Copy link
Contributor Author

Narretz commented May 31, 2018

Yeah the names aren't great. Since they are already verbose we could change it to "timeStripSecondsIfZero" or maybe "timeStripZeroSeconds".
I think since milliseconds are part of seconds "timeSecondsFormat" is fine. Looks like I did a sloppy job changing it everywhere.

@Narretz
Copy link
Contributor Author

Narretz commented May 31, 2018

Oh, and why not include minutes: browsers that support time need hours and minutes and will also always display them even if they are 0.

Copy link
Contributor

@petebacondarwin petebacondarwin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you going to rename timeStripEmptySeconds?


if (isTimeType && isString(ctrl.$options.getOption('timeSecondsFormat'))) {
targetFormat = format.replace('ss.sss', ctrl.$options.getOption('timeSecondsFormat'));
if (targetFormat[targetFormat.length - 1] === ':') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is ugly and would be simpler with:

targetFormat = targetFormat.replace(/:$/, '');

.component('timeExample', {
templateUrl: 'timeExample.html',
controller: function() {
this.time = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(it is only good practice if you are working directly with the scope - in this case you already have an object on the scope $ctrl so it doesn't matter)

@Narretz
Copy link
Contributor Author

Narretz commented Jun 6, 2018

I want to rename it, but which is better - stripZeroSeconds or stripSecondsIfZero?

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
@petebacondarwin
Copy link
Contributor

I preferstripZeroSeconds

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
@Narretz Narretz merged commit 83f7980 into angular:master Jun 12, 2018
@Narretz Narretz deleted the feat-input-timeformat branch June 12, 2018 21:45
Narretz added a commit that referenced this pull request Jun 13, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
4 participants