Skip to content

Commit

Permalink
Fixed: Timezone offset issue in list views
Browse files Browse the repository at this point in the history
Same issue addressed in last fix for negative timezone offsets, was overlooked before.
  • Loading branch information
r3-gabriel committed May 16, 2023
1 parent 0a2f348 commit ed940f3
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 75 deletions.
129 changes: 55 additions & 74 deletions www/comps/inputDate.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,10 @@ let MyInputDateEntryInput = {
},
emits:['update:modelValue'],
computed:{
styles:function() {
return `width:${this.size}ch;`;
},
styles:(s) => `width:${s.size}ch;`,
value:{
get:function() { return this.modelValue; },
set:function() {}
get() { return this.modelValue; },
set(v) {}
}
}
};
Expand Down Expand Up @@ -115,7 +113,7 @@ let MyInputDateEntry = {
emits:['update:modelValue'],
watch:{
modelValue:{
handler: function(v) {
handler(v) {
// fill input fields if value changed
if(v === null) {
this.year = '';
Expand All @@ -142,66 +140,44 @@ let MyInputDateEntry = {
immediate:true
}
},
data:function() {
data() {
return {
year:'', month:'', day:'',
hour:'', minute:'', second:''
};
},
computed:{
isDateOnly:function() {
return this.isDate && !this.isTime;
},
isDateTime:function() {
return this.isDate && this.isTime;
},
isTimeOnly:function() {
return !this.isDate && this.isTime;
},
inputSeparatorSymbol:function() {
if(this.settings.dateFormat.indexOf('/') !== -1)
return '/';

if(this.settings.dateFormat.indexOf('.') !== -1)
return '.';

return '-';
},

/* alternative inputs for mobile devices */
/* uses datetime-local for native datetime inputs on mobile devices */
/* works reliably with format 2019-12-31T12:12:00 */
valueDatetimeInput:{
get:function() {
get() {
return this.modelValue !== null
? `${this.year}-${this.month}-${this.day}T${this.hour}:${this.minute}:${this.second}`
: '';
? `${this.year}-${this.month}-${this.day}T${this.hour}:${this.minute}:${this.second}` : '';
},
set:function(v) {
set(v) {
let d = new Date(v);
if(!isNaN(d.getTime()))
this.$emit('update:modelValue',d.getTime() / 1000);
}
},
valueDateInput:{
get:function() {
get() {
return this.modelValue !== null
? `${this.year}-${this.month}-${this.day}`
: '';
? `${this.year}-${this.month}-${this.day}` : '';
},
set:function(v) {
set(v) {
let d = new Date(v);
if(!isNaN(d.getTime()))
this.$emit('update:modelValue',d.getTime() / 1000);
}
},
valueTimeInput:{
get:function() {
get() {
return this.modelValue !== null
? `${this.hour}:${this.minute}:${this.second}`
: '';
? `${this.hour}:${this.minute}:${this.second}` : '';
},
set:function(v) {
set(v) {
let m = v.match(/^(\d+)\:(\d+)\:(\d+)$/);
if(m !== null && m.length === 4)
return this.$emit('update:modelValue',
Expand All @@ -217,18 +193,30 @@ let MyInputDateEntry = {
}
},

// display
inputSeparatorSymbol:(s) => {
if(s.settings.dateFormat.indexOf('/') !== -1) return '/';
if(s.settings.dateFormat.indexOf('.') !== -1) return '.';
return '-';
},

// simple
isDateOnly:(s) => s.isDate && !s.isTime,
isDateTime:(s) => s.isDate && s.isTime,
isTimeOnly:(s) => !s.isDate && s.isTime,

// stores
capApp: function() { return this.$store.getters.captions.input.date; },
isMobile:function() { return this.$store.getters.isMobile; },
settings:function() { return this.$store.getters.settings; }
capApp: (s) => s.$store.getters.captions.input.date,
isMobile:(s) => s.$store.getters.isMobile,
settings:(s) => s.$store.getters.settings
},
methods:{
// externals
getDateAtUtcZero,
getDateShifted,
getStringFilled,

parseInput:function(name,input) {
parseInput(name,input) {
let d;
let p = parseInt(input);
if(isNaN(p)) return;
Expand Down Expand Up @@ -273,20 +261,20 @@ let MyInputDateEntry = {
}
this.$emit('update:modelValue',Math.floor(d.getTime() / 1000));
},
getInputCaption:function(position) {
getInputCaption(position) {
switch(this.getInputType(position)) {
case 'Y': return this.capApp.inputYear; break;
case 'm': return this.capApp.inputMonth; break;
case 'd': return this.capApp.inputDay; break;
}
},
getInputSize:function(position) {
getInputSize(position) {
return this.getInputType(position) === 'Y' ? 4 : 2;
},
getInputType:function(position) {
getInputType(position) {
return this.settings.dateFormat.substr(position,1);
},
getInputValue:function(position) {
getInputValue(position) {
switch(this.getInputType(position)) {
case 'Y': return this.year; break;
case 'm': return this.month; break;
Expand Down Expand Up @@ -385,7 +373,7 @@ let MyInputDate = {
unixTo: { required:false, default:null }
},
emits:['blurred','focused','set-unix-from','set-unix-to'],
data:function() {
data() {
return {
calendarFresh:false, // new calendar opened, new date range selection
date:new Date(), // date to control calendar navigation
Expand All @@ -399,34 +387,27 @@ let MyInputDate = {
// full day events start and end at 00:00:00 UTC
// if used in datetime context, they can only be used in date range,
// otherwise regular datetime value can appear as full day event
fullDay:function() {

// pure dates are always full day
if(this.isDate && !this.isTime)
return true;

// pure times are never full day
if(!this.isDate && this.isTime)
return false;
fullDay:(s) => {
if(s.isDate && !s.isTime) return true; // pure dates are always full day
if(!s.isDate && s.isTime) return false; // pure times are never full day

// if not pure date, a range is required to allow for full day events
// otherwise we cannot separate regular from full day events
if(!this.isRange)
return false;
if(!s.isRange) return false;

// full day if start and end date are not set or UTC 00:00:00
return (this.unixFrom === null || this.isUnixUtcZero(this.unixFrom))
&& (this.unixTo === null || this.isUnixUtcZero(this.unixTo));
return (s.unixFrom === null || s.isUnixUtcZero(s.unixFrom))
&& (s.unixTo === null || s.isUnixUtcZero(s.unixTo));
},

// date|time inputs
unixFromInput:{
get:function() { return this.unixFrom; },
set:function(v) { this.$emit('set-unix-from',v); }
get() { return this.unixFrom; },
set(v) { this.$emit('set-unix-from',v); }
},
unixToInput:{
get:function() { return this.unixTo; },
set:function(v) {
get() { return this.unixTo; },
set(v) {
// if to unix is smaller, set to from
if(v !== null && v < this.unixFromInput)
v = this.unixFromInput;
Expand All @@ -436,11 +417,11 @@ let MyInputDate = {
},

// start/end date of calendar (month input)
date0:function() { return this.getCalendarCutOff0('month',new Date(this.date.valueOf())) },
date1:function() { return this.getCalendarCutOff1('month',new Date(this.date.valueOf()),this.date0) },
date0:(s) => s.getCalendarCutOff0('month',new Date(s.date.valueOf())),
date1:(s) => s.getCalendarCutOff1('month',new Date(s.date.valueOf()),s.date0),

// stores
capApp:function() { return this.$store.getters.captions.input.date; }
capApp:(s) => s.$store.getters.captions.input.date
},
methods:{
// externals
Expand All @@ -455,21 +436,21 @@ let MyInputDate = {
isUnixUtcZero,

// events
escaped:function() {
escaped() {
this.showCalendar = false;
},
focused:function() {
focused() {
if(!this.isReadonly && !this.showCalendar)
this.showCalendar = true;
},
updateDropdownDirection:function() {
updateDropdownDirection() {
let headersPx = 200; // rough height in px of all headers (menu/form) combined
let calPx = 320; // rough height in px of calendar input
this.showUpwards = this.isDropdownUpwards(this.$el,calPx,headersPx);
},

// actions
toggleCalendar:function() {
toggleCalendar() {
if(!this.showCalendar) {

// reset date range selection
Expand Down Expand Up @@ -501,7 +482,7 @@ let MyInputDate = {
}
this.showCalendar = !this.showCalendar;
},
toggleFullDayRange:function() {
toggleFullDayRange() {
// if range is empty, set both dates to a datetime today
if(this.unixFrom === null && this.unixTo === null) {
let unix = this.getUnixFromDate(this.getDateNoUtcZero(new Date()));
Expand All @@ -521,7 +502,7 @@ let MyInputDate = {
this.$emit('set-unix-to',this.getUnixFromDate(this.getDateFullDayToggled(
new Date(this.unixTo*1000),this.fullDay)));
},
dateSet:function(dSet,shift) {
dateSet(dSet,shift) {
let apply = (d,unixOld) => {
if(!this.fullDay) {
// dates are always UTC zero
Expand Down Expand Up @@ -556,7 +537,7 @@ let MyInputDate = {
this.unixToInput = apply(dSet,this.unixTo);
this.showCalendar = false;
},
setNull:function() {
setNull() {
this.unixFromInput = null;
this.unixToInput = null;
this.showCalendar = false;
Expand Down
7 changes: 6 additions & 1 deletion www/comps/valueRich.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
} from './shared/attribute.js';
import {
getUnixFormat,
getUnixShifted,
getUtcTimeStringFromUnix
} from './shared/time.js';
import {
Expand Down Expand Up @@ -127,6 +128,7 @@ let MyValueRich = {
getHtmlStripped,
getLinkMeta,
getUnixFormat,
getUnixShifted,
getUtcTimeStringFromUnix,
openLink,

Expand Down Expand Up @@ -180,7 +182,10 @@ let MyValueRich = {
case 'integer': // fallthrough
case 'bigint':
switch(atr.contentUse) {
case 'date': this.stringValueFull = this.getUnixFormat(this.value,this.settings.dateFormat); break;
case 'date': // shift to local offset to show correct date
this.stringValueFull = this.value === null ? ''
: this.getUnixFormat(this.getUnixShifted(this.value,true),this.settings.dateFormat);
break;
case 'datetime': this.stringValueFull = this.getUnixFormat(this.value,this.settings.dateFormat + ' H:i'); break;
case 'time': this.stringValueFull = this.getUtcTimeStringFromUnix(this.value); break;
default: directValue = true; break;
Expand Down

0 comments on commit ed940f3

Please sign in to comment.