Pregunta Cómo obtener el meridiano (am / pm) con momentosjs y angularjs


Tengo una pregunta sobre los momentos de la biblioteca.js, tengo una aplicación en angularjs donde tengo seis elementos seleccionados para el año, mes, día, hora, minutos y formato am / pm. Estoy usando el siguiente momento de formato para construir la fecha de formato m ('YYYY-MM-DD hh: mm: ss a).

El código es el siguiente:

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'))

Obtengo los datos m.hour (), m.minute (), etc, pero hay una manera de obtener el formato am / pm, no he encontrado nada al respecto, algo tal vez como m.meridian () => "am "or" pm ".

Construiría la matriz pasando como parámetro si am o pm, y luego obtendría cualquier fecha si am o pm fecha.


5
2017-09-26 22:46


origen


Respuestas:


Unas pocas cosas:

  • La palabra que estás buscando es "meridiem"no "meridiano". Es una palabra latina que significa "mediodía". a.m. es "ante meridiem" (antes del medio día) y P.M. es "post meridiem" (después del mediodía).

  • los .hours() función y la matriz de entrada pasó a la moment el constructor espera horas de un reloj de 24 horas, de 0 a 23. No hay una función incorporada para aceptar o emitir un valor de reloj de 12 horas o un meridiem (am / pm).

  • Las funciones de análisis y formateo en el momento tienen opciones para horas de reloj de 12 horas (h o hh) y meridiem (A o a), pero no está analizando o formateando en su caso de uso, por lo que sería un poco torpe de usar. En particular, se basan en la configuración regional actual del momento, por lo que probar una cadena sería problemático si la configuración regional no se fijara en un idioma específico.

  • Puede usar estas funciones simples para convertir de meridiano de 12 horas + a 24 horas y viceversa. No son específicos del momento, por lo que también puede usarlos con el Date objeto o en otro lugar.

    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
        }
    }
    

    Para probar estas funciones:

    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);
      }
    }
    
  • Además, ten cuidado cuando llamas .month() para obtener el número de mes, los resultados son 0-11, no 1-12. Lo mismo es cierto cuando se construye la matriz de entrada. Su menú desplegable necesita usar 0-11, o necesita agregar o restar 1 en consecuencia.


7
2017-09-27 01:03



También podrías hacer algo como m.format('a')


8
2017-11-09 03:22



La otra respuesta es muy buena. Me ayudó a crear mi demo porque sin ella me habría perdido el punto del mes (de 0 a 11).

Pero no es necesario crear la función meridiem porque ya está implementada en moment.js. El punto es que el uso no está muy claro en los documentos.

Puedes usar el meridiem funciona así:

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

Si necesitas un booleano en lugar de AM/PM cadena puede pasar la cadena AM / PM a curDate.localeData().isPM(meridiem). Eso volverá verdadero o falso.

El punto con el mes que no desea mostrar de 0 a 11 en su selección puede ser fijado por un displayLabel Función que incrementará cada valor de la matriz del mes. Luego, se mostrará de 1 a 12, pero se almacenará de 0 a 11. Si está escribiendo una directiva que podría manejarse mejor con un $parser / $formatter funcion de ngModel.

Por favor, eche un vistazo a la demostración a continuación o en este jsfiddle.

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

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

function MomentUTCFilter() {
	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
           	// 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('_')
        };
	}
    
    function displayLabel(key, value) {
    	if (key === 'month') {
        	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 = [];
    	for(i=from; i<=to; i++) {
        	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>


1
2017-09-27 19:17