Angular 2 Material 2 datepicker date format

前端 未结 14 2211
悲哀的现实
悲哀的现实 2020-11-28 23:21

I need help. I don\'t know how to change the date format of the material 2 datepicker. I\'ve read documentation but I don\'t understand what I actually need to do. Output da

相关标签:
14条回答
  • 2020-11-28 23:34

    Igor's answer didn't work for me so I asked directly on Angular 2 Material's github and someone gave me that answer which worked for me :

    1. First write your own adapter :

      import { NativeDateAdapter } from "@angular/material";
      
      
      export class AppDateAdapter extends NativeDateAdapter {
      
          format(date: Date, displayFormat: Object): string {
      
              if (displayFormat === 'input') {
      
                  const day = date.getDate();
                  const month = date.getMonth() + 1;
                  const year = date.getFullYear();
      
                  return `${day}-${month}-${year}`;
              }
      
              return date.toDateString();
          }
      }
      
    2. Create your date format :

      export const APP_DATE_FORMATS =
      {
          parse: {
              dateInput: { month: 'short', year: 'numeric', day: 'numeric' },
          },
          display: {
              dateInput: 'input',
              monthYearLabel: { year: 'numeric', month: 'numeric' },
              dateA11yLabel: { year: 'numeric', month: 'long', day: 'numeric' },
              monthYearA11yLabel: { year: 'numeric', month: 'long' },
          }
      };
      
    3. Provide those two to your module

      providers: [
              {
                  provide: DateAdapter, useClass: AppDateAdapter
              },
              {
                  provide: MAT_DATE_FORMATS, useValue: APP_DATE_FORMATS
              }
          ]
      

    More infos here

    EDIT: For those who are having the trouble of the manual input is being not respected with the format, you may override the parse(value: any) function from the NativeDateAdapter as follows.

    parse(value: any): Date | null {
        const date = moment(value, 'DD/MM/YYYY');
        return date.isValid() ? date.toDate() : null;
    }
    

    So, the custom adapter will take the final shape as follows.

    import { NativeDateAdapter } from "@angular/material";
    import * as moment from 'moment';
    
    export class AppDateAdapter extends NativeDateAdapter {
    
        format(date: Date, displayFormat: Object): string {
            if (displayFormat === 'input') {
    
                const day = date.getDate();
                const month = date.getMonth() + 1;
                const year = date.getFullYear();
    
                return `${day}/${month}/${year}`;
            }
    
            return date.toDateString();
        }
    
        parse(value: any): Date | null {
            const date = moment(value, environment.APP_DATE_FORMAT);
            return date.isValid() ? date.toDate() : null;
        }
    }
    
    0 讨论(0)
  • 2020-11-28 23:37

    Robouste worked perfect!!

    I made easy one (Angular 4 "@angular/material": "^2.0.0-beta.10") first made datepicker.module.ts

    
    
        import { NgModule }  from '@angular/core';
        import { MdDatepickerModule, MdNativeDateModule, NativeDateAdapter, DateAdapter, MD_DATE_FORMATS  }  from '@angular/material';
    
        class AppDateAdapter extends NativeDateAdapter {
            format(date: Date, displayFormat: Object): string {
                if (displayFormat === 'input') {
                    const day = date.getDate();
                    const month = date.getMonth() + 1;
                    const year = date.getFullYear();
                    return `${year}-${month}-${day}`;
                } else {
                    return date.toDateString();
                }
            }
        }
    
        const APP_DATE_FORMATS = {
        parse: {
        dateInput: {month: 'short', year: 'numeric', day: 'numeric'}
        },
        display: {
        // dateInput: { month: 'short', year: 'numeric', day: 'numeric' },
        dateInput: 'input',
        monthYearLabel: {year: 'numeric', month: 'short'},
        dateA11yLabel: {year: 'numeric', month: 'long', day: 'numeric'},
        monthYearA11yLabel: {year: 'numeric', month: 'long'},
        }
        };
    
        @NgModule({
        declarations:  [ ],
        imports:  [ ],
            exports:  [ MdDatepickerModule, MdNativeDateModule ],
        providers: [
        {
            provide: DateAdapter, useClass: AppDateAdapter
        },
        {
            provide: MD_DATE_FORMATS, useValue: APP_DATE_FORMATS
        }
        ]
        })
    
        export class DatePickerModule {
    
        }
    

    just import it (app.module.ts)

    
        import {Component, NgModule, VERSION,  ReflectiveInjector}   from '@angular/core'//NgZone,
        import { CommonModule }              from '@angular/common';
        import {BrowserModule}               from '@angular/platform-browser'
        import { BrowserAnimationsModule }        from '@angular/platform-browser/animations';
        import { FormsModule }              from '@angular/forms';
        import { DatePickerModule }            from './modules/date.picker/datepicker.module';
    
        @Component({
        selector: 'app-root',
        template: `
        <input (click)="picker.open()" [mdDatepicker]="picker" placeholder="Choose a date" [(ngModel)]="datepicker.SearchDate"  >
        <md-datepicker-toggle mdSuffix [for]="picker"></md-datepicker-toggle>
        <md-datepicker #picker touchUi="true"  ></md-datepicker>
        `,
        })
    
    
        export class App{
            datepicker = {SearchDate:new Date()}
            constructor( ) {}
    
            }
    
        @NgModule({
        declarations: [ App ],
        imports: [ CommonModule, BrowserModule, BrowserAnimationsModule, FormsModule, DatePickerModule],
        bootstrap: [ App ],
        providers: [   ]//NgZone
        })
        export class AppModule {}
    
    
    0 讨论(0)
  • 2020-11-28 23:41

    Here is the only solution I found for this one:

    First, create const:

    const MY_DATE_FORMATS = {
       parse: {
           dateInput: {month: 'short', year: 'numeric', day: 'numeric'}
       },
       display: {
           // dateInput: { month: 'short', year: 'numeric', day: 'numeric' },
           dateInput: 'input',
           monthYearLabel: {year: 'numeric', month: 'short'},
           dateA11yLabel: {year: 'numeric', month: 'long', day: 'numeric'},
           monthYearA11yLabel: {year: 'numeric', month: 'long'},
       }
    };
    

    Then you have to extend NativeDateADapter:

    export class MyDateAdapter extends NativeDateAdapter {
       format(date: Date, displayFormat: Object): string {
           if (displayFormat == "input") {
               let day = date.getDate();
               let month = date.getMonth() + 1;
               let year = date.getFullYear();
               return this._to2digit(day) + '/' + this._to2digit(month) + '/' + year;
           } else {
               return date.toDateString();
           }
       }
    
       private _to2digit(n: number) {
           return ('00' + n).slice(-2);
       } 
    }
    

    In format function, you can choose whatever format you want

    And the last step, you have to add it into module providers:

    providers: [
        {provide: DateAdapter, useClass: MyDateAdapter},
        {provide: MD_DATE_FORMATS, useValue: MY_DATE_FORMATS},
    ],
    

    And that's it. I can not believe that there is no some easy way to change date format through the @Input but let's hope it will be implemented in some future version of material 2 (currently beta 6).

    0 讨论(0)
  • 2020-11-28 23:42

    Why to not use Angular DatePipe?

    import {Component} from '@angular/core';
    import {DateAdapter, MAT_DATE_FORMATS, NativeDateAdapter} from '@angular/material';
    import {FormControl} from '@angular/forms';
    import {DatePipe} from '@angular/common';
    
    export const PICK_FORMATS = {
        parse: {dateInput: {month: 'short', year: 'numeric', day: 'numeric'}},
        display: {
            dateInput: 'input',
            monthYearLabel: {year: 'numeric', month: 'short'},
            dateA11yLabel: {year: 'numeric', month: 'long', day: 'numeric'},
            monthYearA11yLabel: {year: 'numeric', month: 'long'}
        }
    };
    class PickDateAdapter extends NativeDateAdapter {
        format(date: Date, displayFormat: Object): string {
            if (displayFormat === 'input') {
                return new DatePipe('en-US').transform(date, 'EEE, MMM dd, yyyy');
            } else {
                return date.toDateString();
            }
        }
    }
    @Component({
        selector: 'custom-date',
        template: `<mat-form-field>
                       <input matInput [formControl]="date" />
                       <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
                       <mat-datepicker #picker></mat-datepicker>
                   </mat-form-field>`,
        providers: [
            {provide: DateAdapter, useClass: PickDateAdapter},
            {provide: MAT_DATE_FORMATS, useValue: PICK_FORMATS}
        ]
    })
    export class DateComponent {
        date = new FormControl(new Date());
        constructor() {}
    }
    
    0 讨论(0)
  • 2020-11-28 23:43

    original idea of Arthur z and Gil Epshtain, I have changed moment to date-fns. tested in angular @angular/material": "^10.0.2.

    Create CustomDateAdapter.ts and implement it like this:

    import { NativeDateAdapter } from "@angular/material/core";
    import { format } from 'date-fns';
    import { es } from 'date-fns/locale'
    
    export class CustomDateAdapter extends NativeDateAdapter {
        format(date: Date, displayFormat: Object): string {
            var formatString = (displayFormat === 'input')? 'DD.MM.YYYY' : 'dd-MM-yyyy';
            return format(date, formatString, {locale: es});
        }
    }
    

    In your app.module.ts:

    import { DateAdapter } from '@angular/material';
    
    providers: [
        ...
        {
            provide: DateAdapter, useClass: CustomDateAdapter
        },
        ...
    ]
    
    0 讨论(0)
  • 2020-11-28 23:45

    There's a high chance that you already use a library that provides you with an convinient way of manipulating (parsing, validating, displaying, etc.) dates and times in JavaScript. If you dont, take a look at one of them, for example moment.js.

    Implementing your custom adapter using moment.js would look like this.

    Create CustomDateAdapter.ts and implement it like this:

    import { NativeDateAdapter } from "@angular/material";
    import * as moment from 'moment';
    
    export class CustomDateAdapter extends NativeDateAdapter {
        format(date: Date, displayFormat: Object): string {
            moment.locale('ru-RU'); // Choose the locale
            var formatString = (displayFormat === 'input')? 'DD.MM.YYYY' : 'LLL';
            return moment(date).format(formatString);
        }
    }
    

    In your app.module.ts:

    import { DateAdapter } from '@angular/material';
    
    providers: [
        ...
        {
            provide: DateAdapter, useClass: CustomDateAdapter
        },
        ...
    ]
    

    That's it. Simple, easy and no need of reinventing bicycles.

    0 讨论(0)
提交回复
热议问题