I'm making a PWA on angular 8 / ionic 5. Users can create events and have them listed on a feed page. Problem is, that the date and the time of each event does not get displayed and gives the error "NaN" on iphones/iOS devices. Both date and time get their information from start_at which is the time in the format of "hh:mm:ss".
Following code shows how we receive the response data from our MySQL php laravel server for listing the events:
getTodos() {
console.log("arrived to gettodos");
var id = this.userInfo.id
this.todoService.getTodos('', '', '', id, false).subscribe(res => {
console.log("res", res);
console.log("frimes", res['frimes']);
// debugger;
// console.log(res);
if (res['code'] === 200) {
// console.log(res['data']);
const userFrimes: any[] = res['frimes'];
this.todos = [] as any[];
console.log(userFrimes);
if (userFrimes && userFrimes.length > 0) {
userFrimes.forEach(uf => {
var timeofFrime = this.formatAMPM(uf.start_at);
if (!this.todoService.isFrimeExpired(uf.start_at)) {
this.todos.push({
owner: this.userInfo.username,
title: uf.title,
message: uf.description,
date: uf.start_at,
time: timeofFrime,
max: uf.max,
guests: uf.member.length, //uf.guests == null ? 0 : uf.guests,
frime_id: uf.id,
status: uf.status,
user_id: uf.user_id
});
}
});
}
} else if (res['code'] === 205) {
} else if (res['code'] === 401) {
}
}, err => {
//this.errorMessage = err.message;
console.log(err);
});
}
here you can see that the properties date and time are being fetched for the formatAMPM() function and changed to the AM/PM date format.
formatAMPM(d) {
let dd = d + " UTC";
let date = new Date(dd);
var hours = date.getHours();
var minutes = date.getMinutes();
var ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12; // the hour '0' should be '12'
var min = minutes < 10 ? '0' + minutes : minutes;
var strTime = hours + ':' + min + ' ' + ampm;
return strTime;
}
here the final date string gets displayed in the pipe fields where it shows the "NaN" error on ios.
the error itself says:
ERROR Error: InvalidPipeArgument: 'Unable to convert "2021-05-19 17:15:38" into a date' for pipe 'Re'.
what does 'Re' mean btw?
<ion-col size="3" class="date-wrapper">
<h3 class="notification-date">
{{ item.date | date: "shortDate" }}
</h3>
<h3 class="notification-date">
{{ item.time | date: "HH:mm" }}
</h3>
<h3 class="notification-date">{{ item.guests + '/' + item.max }}</h3>
</ion-col>
hope you can help me fixing this, because this is giving me soooo many headachse lately...
thanks in advance!
ok i have fixed it by adding this line of code:
d = d.replace(" ", "T");
the date came in a format like dd-MM-yyyy HH:mm:ss and i needed to add the "T" so it is like dd-MM-yyyyTHH:mm:ss
formatAMPM(d) {
d = d.replace(" ", "T");
let dd = d + " UTC";
let date = new Date(dd);
var hours = date.getHours();
var minutes = date.getMinutes();
var ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12; // the hour '0' should be '12'
var min = minutes < 10 ? '0' + minutes : minutes;
var strTime = hours + ':' + min + ' ' + ampm;
return strTime;
}
Related
I have a datepicker. When I select a date, automatically next two days should also get selected. In total, 3 business days should get selected.
I have tried below code but it's not working.
$('.date-pick').datePicker({
createButton:false,
displayClose:true,
closeOnSelect:false,
selectMultiple:true,
numSelectable:3
});
Your post did not include a details about the output or selection process. Here is an example for your review:
$(function() {
function dayNumOfWeek(d) {
var week = {
"Sun": 0,
"Mon": 1,
"Tue": 2,
"Wed": 3,
"Thu": 4,
"Fri": 5,
"Sat": 6,
}
return week[d];
}
$(".date-pick").datepicker({
showButtonPanel: true,
closeText: "Close",
beforeShowDay: $.datepicker.noWeekends,
onSelect: function(dt) {
var myDays = [
new Date(dt),
new Date(dt),
new Date(dt)
];
var dow = myDays[0].getDay();
var dp = $(".date-pick");
console.log("Selected: " + dow + "/7, " + dt, myDays);
switch (dow) {
case 1:
case 2:
case 3:
console.log("mtw");
myDays[1].setDate(myDays[1].getDate() + 1);
myDays[2].setDate(myDays[2].getDate() + 2);
break;
case 4:
console.log("rfm");
myDays[1].setDate(myDays[1].getDate() + 1);
myDays[2].setDate(myDays[2].getDate() + 4);
break;
case 5:
console.log("fmt");
myDays[1].setDate(myDays[1].getDate() + 3);
myDays[2].setDate(myDays[2].getDate() + 4);
break;
};
var fDT = [];
console.log("Format Dates");
var mm, dd, yy;
for (var i = 0; i < 3; i++) {
console.log(i, myDays[i]);
mm = myDays[i].getMonth() + 1;
dd = myDays[i].getDate();
yy = myDays[i].getFullYear();
mm = (mm < 10 ? "0" + mm : mm);
dd = (dd < 10 ? "0" + dd : dd);
fDT[i] = mm + "/" + dd + "/" + yy;
};
console.log("Formatted:", fDT);
dp.val(fDT.join(", "));
return false;
}
});
});
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.12.4.js"></script>
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
Select Date: <input type="text" class="date-pick" />
When you make a selection, you can manage what is done via onSelect that receives the date in text. Since you are working with business days of the week, mon to fri, and months, you want to make sure that selecting a date near the end of the week and end of the month calculates the next few days properly.
Converting to JavaScript Date type, you can leverage a lot of the tools to calculate the next few days without issues. You have 3 scenarios: Mon, Tues, Wed. as 1, Thur, Fri, Mon as 2, and Fri, Mon, Tue as 3.
When you make a selection, it picks the next 2 days from the business week.
I want to show TimeSpan values on my Value axis. Chart is working fine for numeric but if I change to TimeSpan nothing is showing. I checked the data and it's ok. If TimeSpan is not supported is there a way to format minutes in int values to be shown as Time (ie ,,6h 34 min")
Here is my chart:
#(Html.Kendo().Chart<MachineWorkTimeChartViewModel>()
.Name("chartMachineWorkTime")
.DataSource(ds => ds.Read(read => read.Action("MachineWorkTimeChart_Read", "Charts")
.ChartArea(chartArea => chartArea
.Background("transparent")
)
.Series(series =>
{
series.Bar(e => e.WorkTimeSpan).Name("Time of work");
})
.CategoryAxis(axis => axis
.Name("label-axis")
.Categories(e => e.MachineName)
.Line(line => line.Visible(false))
)
)
and here is my ViewModel:
public class MachineWorkTimeChartViewModel
{
public int WorkMinutes { get; set; }
public string MachineName { get; set; }
public TimeSpan WorkTimeSpan => TimeSpan.FromMinutes(WorkMinutes);
}
Based on your answer ezanker and modified js function from jgritty link
I got it to work (I didn't want to use an external js library).
Here is full example:
#(Html.Kendo().Chart<MachineWorkTimeChartViewModel>()
.Name("chartMachineWorkTime")
.DataSource(ds => ds.Read(read => read.Action("MachineWorkTimeChart_Read", "Charts")
.ChartArea(chartArea => chartArea
.Background("transparent")
)
.Series(series =>
{
series.Bar(e => e.WorkMinutes).Name("Time of work");
})
.CategoryAxis(axis => axis
.Name("series-axis")
.Line(line => line.Visible(false))
)
.CategoryAxis(axis => axis
.Name("label-axis")
.Categories(e => e.MachineName)
)
.ValueAxis(axis => axis
.Numeric()
.Labels(labels => labels.Format("{0} min.")
.Template("#= getTimeSpanFromMinutes(value) #"))
// Move the label-axis all the way down the value axis
.AxisCrossingValue(0, int.MinValue)
)
.Tooltip(tooltip => tooltip
.Visible(true)
.Format("{0}%")
.Template("#= getTimeSpanFromMinutes(value) #")
))
<script>
function getTimeSpanFromMinutes(newMinutes) {
var minsPerYear = 24 * 365 * 60;
var minsPerMonth = 24 * 30 * 60;
var minsPerWeek = 24 * 7 * 60;
var minsPerDay = 24 * 60;
var minsPerHour = 60;
var minutes = newMinutes;
var years = Math.floor(minutes / minsPerYear);
minutes = minutes - years * minsPerYear;
var months = Math.floor(minutes / minsPerMonth);
minutes = minutes - months * minsPerMonth;
var weeks = Math.floor(minutes / minsPerWeek);
minutes = minutes - weeks * minsPerWeek;
var days = Math.floor(minutes / minsPerDay);
minutes = minutes - days * minsPerDay;
var hours = Math.floor(minutes / minsPerHour);
minutes = minutes - hours * minsPerHour;
var timeSpan = "";
if (years > 0)
timeSpan += years + " years ";
if (months > 0)
timeSpan += months + " months ";
if (weeks > 0)
timeSpan += weeks + " weeks ";
if (days > 0)
timeSpan += weeks + " days ";
if (hours > 0)
timeSpan += hours + " hours ";
if (minutes > 0)
timeSpan += minutes + " min. ";
return timeSpan;
}</script>
I have this piece of code:
(function() {
"use strict";
angular
.module("Default")
.directive(
"numberToTime",
["$rootScope", "$compile", "$log",
function($rootScope, $compile, $log) {
return {
"restrict": "A",
"transclude": true,
"replace": true,
"scope": {
"time": "="
},
"link": function(scope, ele, attrs) {
/**
* Function to add one serie of string to another untill complete
* certain length
*
*/
var _lpad = function(str, padString, length) {
while (str.length < length) {
str = padString + str;
}
return str;
};
/**
* Function to turn a number into time format
*/
var _2time = function(s, hideDays, hideSeconds) {
var d = Math.floor(s / (24 * 60 * 60));
s -= d * (24 * 60 * 60);
var h = Math.floor(s / (60 * 60));
s -= h * (60 * 60);
var m = Math.floor(s / 60);
s -= m * 60;
s = Math.floor(s);
var time = "";
if (!hideDays) {
time += d > 0 ? d + " day" + (d > 1 ? "s" : "") + ", " : "";
}
time += _lpad(h.toString(), '0', 2) + ":" + _lpad(m.toString(), '0', 2) + (hideSeconds ? "" : (":" + _lpad(s.toString(), '0', 2)));
return time;
};
var _setTime = function(time) {
var _time = _2time(time, attrs.hidedays != "false", attrs.hideseconds != "false");
ele.html(_time);
};
scope.$watch("time", function() {
_setTime(scope.time);
}, true);
}
};
}
]
)
;
})();
It works ok, if I have something like:
<span number-to-time time="time"></span>
where
$scope.time = 1234;
It turns that number into readable time format. However, in iOS it does not updates the html.
I have it in a player, and if I log the html() content of ele, it says it has the correct time, but in the page I still see 00:00:00, and the time does not updates correctly. What am I doing wrong?
FIXING
Instead of using .html use .text:
ele.text(_time);
Looks like your page is not being rendered. Instead of using html, use text.
var _setTime = function(time) {
var _time = _2time(time, attrs.hidedays != "false", attrs.hideseconds != "false");
ele.text(_time);
};
You can find more information here: http://bit.ly/1E4cMxG
I'm trying to enable only Thursdays and Sundays but also disable some specific Sundays or Thursdays.
I'm trying with this function but it's not working yet:
<script>
var unavailableDates = ["2013-03-31", "2013-03-24"];
function disabledays(date) {
ymd = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
if ($.inArray(ymd, unavailableDates) == 0) {
return [false, "", "Unavailable"]
} else {
//Show only sundays and thuersdays
var day = date.getDay();
return [(day == 0 || day == 4)];
}
$('#txtDate').datepicker({
beforeShowDay: disabledays
})
</script>
Two problems:
The code that builds a date string does not add a 0 to the month portion. You could change your unavailableDates array.
You need to check the return value of $.indexOf to see if it's >= 0 instead of just equal to zero.
With both changes:
var unavailableDates = ["2013-3-31", "2013-3-24"];
function disabledays(date) {
var ymd = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
if ($.inArray(ymd, unavailableDates) >= 0) {
return [false, "", "Unavailable"];
} else {
//Show only sundays and thuersdays
var day = date.getDay();
return [(day == 0 || day == 4)];
}
}
$('#txtDate').datepicker({
beforeShowDay: disabledays
});
Example: http://jsfiddle.net/XJKbV/
My string format is: M/d/yyyy h:m:s aa
Now, I want to change it in yyyy-MM-ddTHH:mm:ss format.
How can I change it in this format. Please tell me appropriate solution
The method getConvertedDate(String), will do a plain text parsing for conversion.
private String getConvertedDate(String inputDate) {
// extract and adjust Month
int index = inputDate.indexOf('/');
String month = inputDate.substring(0, index);
if (month.length() < 2) {
month = "0" + month;
}
// extract and adjust Day
inputDate = inputDate.substring(index + 1);
index = inputDate.indexOf('/');
String day = inputDate.substring(0, index);
if (day.length() < 2) {
day = "0" + day;
}
// extract Year
inputDate = inputDate.substring(index + 1);
index = inputDate.indexOf(' ');
String year = inputDate.substring(0, index);
// extract Hour
inputDate = inputDate.substring(index + 1);
index = inputDate.indexOf(':');
String hour = inputDate.substring(0, index);
// extract and adjust Minute
inputDate = inputDate.substring(index + 1);
index = inputDate.indexOf(':');
String minute = inputDate.substring(0, index);
if (minute.length() < 2) {
minute = "0" + minute;
}
// extract and adjust Second
inputDate = inputDate.substring(index + 1);
index = inputDate.indexOf(' ');
String second = inputDate.substring(0, index);
if (second.length() < 2) {
second = "0" + second;
}
// extract AM/PM marker
// adjust hour, +12 for PM
inputDate = inputDate.substring(index + 1);
String am_pm_marker = inputDate.substring(0);
if (am_pm_marker.equalsIgnoreCase("pm")) {
int hourValue = 0;
try {
hourValue = Integer.parseInt(hour);
} catch (Exception e) {
}
hourValue += 12;
hour = "" + hourValue;
if (hour.length() < 2) {
hour = "0" + hour;
}
} else {
if (hour.length() < 2) {
hour = "0" + hour;
}
}
String outputDate = year + "-" + month + "-" + day;
outputDate += "T" + hour + ":" + minute + ":" + second;
return outputDate;
}
Sample input and output:
String input = "04/01/2012 9:55:47 pm";
System.out.println("Output: " + getConvertedDate(input));
// Output: 2012-04-01T21:55:47
Date date = (Date)new SimpleDateFormat("M/d/yyyy h:m:s aa").parse(your_string_date);
String finalFormat = new SimpleDateFormat("yyyy-MM-ddTHH:mm:ss").format(date)
Basically the first SimpleDateFormat recognizes your original format and parses it into a Date. Then the second one formats the date object to what you need.
I don't have jdk around to test here, but it should work.
Check this links for format syntax in case something doesn't work:
http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html