2015-09-26 15 views
5

Ho una domanda sulla libreria moments.js, ho un'applicazione in angularjs dove ho sei elementi selezionati per l'anno, mese, giorno, ora, minuti e formato am/pm. Sto usando il seguente formato per creare la data di m.format ('AAAA-MM-GG hh: mm: ss a).Come ottenere il meridiano (am/pm) con momentsjs e angularjs

Il codice è il seguente:

var m = moment([scope.val.year, scope.val.month, scope.val.date, scope.val.hour, scope.val.minute]); //build date 

model.$setViewValue(m.format('YYYY-MM-DD hh:mm:ss a')) 

ottengo i dati m.hour(), m.minute(), ecc, ma c'è un modo per ottenere il formato am/pm, non ho trovato nulla a riguardo, qualcosa forse come m.meridian() => "am "or" pm ".

Vorrei costruire l'array passando come parametro se am o pm, e quindi anche ottenere da qualsiasi data se am o pm date.

+2

aspetto nella documentazione formato momento ... è lì – charlietfl

+0

@charlietfl - in realtà, no, non lo è. –

+0

@MattJohnson assicuratevi che sia 'A' o' a' ... http://momentjs.com/docs/#/displaying/ – charlietfl

risposta

6

Un paio di cose:

  • La parola che stai cercando è "meridiem", non "meridian". È una parola latina che significa "mezzogiorno". A.M. è "ante meridiem" (prima di mezzogiorno) e P.M. è "post meridiem" (dopo la metà giornata).

  • La funzione .hours() e la matrice di input passato al costruttore moment sia aspettano ore a 24 ore, da 0 a 23. Non v'è alcuna funzione incorporata per accettare o uscita un valore di 12 ore, o un meridiem (am/pm).

  • Le funzioni di analisi e la formattazione in momento hanno opzioni per 12 ore ore d'orologio (h o hh) e meridiem (A o a), ma non sei l'analisi o la formattazione nel vostro caso d'uso, in modo che sarebbe essere un po 'goffo da usare In particolare, si basano sulle attuali impostazioni locali del momento, quindi testare una stringa sarebbe problematico se le impostazioni internazionali non fossero fissate su una lingua specifica.

  • È possibile utilizzare queste semplici funzioni per convertire da 12 ore + meridiem a 24 ore e viceversa. Non sono specifici del momento, quindi puoi utilizzarli anche con l'oggetto Date o altrove.

    function hours12to24(h, pm) { 
        return h == 12 ? pm ? 12 : 0 : pm ? h + 12 : h; 
    } 
    
    function hours24to12(h) { 
        return { 
         hour : (h + 11) % 12 + 1, 
         pm : h >= 12 
        } 
    } 
    

    Per verificare queste funzioni:

    function test() { 
        for (var i = 0; i <= 23; i++) { 
        var x = hours24to12(i); 
        var h = hours12to24(x.hour, x.pm); 
        console.log(i + " == " + x.hour + (x.pm ? " pm" : " am") + " == " + h); 
        } 
    } 
    
  • Inoltre, fare attenzione quando si chiama .month() per ottenere il numero del mese, i risultati sono 0-11, non 1-12. Lo stesso è vero quando si costruisce l'array di input. Il tuo menu a discesa deve utilizzare 0-11 oppure devi aggiungere o sottrarre 1 di conseguenza.

+0

Grazie, mi è stata molto utile la tua soluzione. – ojedawinder

1

L'altra risposta è molto buona. Mi ha aiutato a creare il mio demo perché senza questo mi sarebbe mancato il punto del mese (da 0 a 11).

Ma non è necessario creare la funzione di meridiem perché è già implementata in moment.js. Il punto è che l'uso non è molto chiaro dai documenti.

È possibile utilizzare la funzione meridiem in questo modo:

var curDate = moment().hour(yourHour); // create a moment date with the hour you'd like to test 
var meridiem = curDate 
      .localeData().meridiem(hour); // will return AM/PM String 

Se avete bisogno di un valore booleano invece di AM/PM stringa si può passare la stringa AM/PM per curDate.localeData().isPM(meridiem). Ciò restituirà vero o falso.

Il punto con il mese in cui non si desidera visualizzare da 0 a 11 nella selezione può essere risolto con una funzione displayLabel che incrementerà ogni valore dell'array del mese. Quindi verrà visualizzato da 1 a 12 ma memorizzato come da 0 a 11. Se si sta scrivendo una direttiva che potrebbe essere gestita meglio da una funzione $parser/$formatter di ngModel.

Si prega di dare un'occhiata alla demo di seguito o a questo .

angular.module('demoApp', []) 
 
\t .filter('momentDate', MomentDateFilter) 
 
\t .filter('momentUTC', MomentUTCFilter) 
 
\t .controller('MainController', MainController); 
 

 
function MomentDateFilter() { 
 
\t return function(input, format) { 
 
     return moment(input).format(format); 
 
    }; 
 
} 
 

 
function MomentUTCFilter() { 
 
\t return function(input, format) { 
 
     return moment.utc(input).format(format); 
 
    }; 
 
} 
 

 
function MainController($scope, $log) { 
 
    var vm = this, 
 
     now = moment(); 
 
    
 
    vm.checkHour = checkHour; 
 
    vm.dateSelect = dateSelection(); 
 
    vm.displayLabel = displayLabel; 
 
    vm.now = now; 
 
    vm.selected = { 
 
     "day": 27, 
 
     "month": 8, 
 
     "year": 2015, 
 
     "hour": 18, 
 
     "meridiem": "PM", 
 
     "minutes": 6, 
 
     "seconds": 20 
 
    }; 
 
    
 
    function dateSelection() { 
 
     return { // generated on every page load for demo 
 
      \t // better store the generate object as json and load it 
 
      day: createRange(1,31), 
 
      month: createRange(0,11), 
 
      year: createRange(1900, 2100), 
 
      hour: createRange(0,24), 
 
      minutes: createRange(0,59), 
 
      seconds: createRange(0,59), 
 
      meridiem: 'AM_PM'.split('_') 
 
     }; 
 
\t } 
 
    
 
    function displayLabel(key, value) { 
 
    \t if (key === 'month') { 
 
     \t value++; // increment month for correct month value 1 to 12 
 
     } 
 
     return value; 
 
    } 
 
    
 
    function checkHour(key, hour) { // updates meridiem (AM/PM) 
 
     if (key === 'hour') { 
 
      var curDate = moment().hour(hour); 
 
      //console.log('check hour', hour, curDate.hour(), curDate.localeData()); 
 
      vm.selected.meridiem = curDate 
 
       .localeData().meridiem(hour); 
 
      //console.log(curDate 
 
      // .localeData().isPM(vm.selected.meridiem)); 
 
     } 
 
     //console.log('changed', key); 
 
    } 
 
    //console.log(this.dateSelect); 
 
    function createRange(from, to) { 
 
     var arr = []; 
 
    \t for(i=from; i<=to; i++) { 
 
     \t arr.push(i); 
 
     } 
 
     //console.log(arr); 
 
     return arr; 
 
    } 
 
    
 
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.0/angular.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script> 
 
<div ng-app="demoApp" ng-controller="MainController as mainCtrl" class="container-fluid"> 
 
    <form class="form-inline"> 
 
     <div ng-repeat="(key, array) in mainCtrl.dateSelect" class="form-group"> 
 
      <label>{{key}}</label><select class="form-control" ng-change="mainCtrl.checkHour(key, array[mainCtrl.selected[key]])" ng-model="mainCtrl.selected[key]" ng-options="value as mainCtrl.displayLabel(key, value) for value in mainCtrl.dateSelect[key]" ng-disabled="key === 'meridiem'"> 
 
      </select> 
 
     </div> 
 
    </form> 
 
    selected: <pre>{{mainCtrl.selected|json}}</pre> 
 
    raw date (unformatted, UTC): {{mainCtrl.selected | momentUTC}}<br/> 
 
    date formatted (meridiem locale): {{mainCtrl.selected | momentUTC : 'LLLL' }}<br/> 
 
    
 
    
 
    now (momentjs) {{mainCtrl.now}} 
 
</div>

+0

Grazie per il vostro aiuto, la soluzione di Matt e la vostra soluzione ha funzionato per me. – ojedawinder

6

Si potrebbe anche fare qualcosa di simile m.format('a')