Daterangepicker dates are wrong - daterangepicker

I am using this daterangepicker https://www.daterangepicker.com/ but somehow it displays wrong dates.
For example: Today it is the Sunday, 22th November 2020, but the daterangepicker says the 22th Novemeber 2020 is a Monday.
Example
and here is my configuration:
$('#singledaterange').daterangepicker({
"locale": {
"format": "D. MMM YYYY",
"separator": " - ",
"applyLabel": "OK",
"cancelLabel": "Abbrechen",
"fromLabel": "Von",
"toLabel": "Bis",
"weekLabel": "W",
"daysOfWeek": [
"Mo",
"Di",
"Mi",
"Do",
"Fr",
"Sa",
"So"
],
"monthNames": [
"Januar",
"Februar",
"März",
"April",
"Mai",
"Juni",
"Juli",
"August",
"September",
"Oktober",
"November",
"Dezember"
],
"firstDay": 0
},
"minDate": moment(),
});

I solved it. It was obviously my fault.
By default, Sunday is the first day of the week, so I had to put Sunday first in the daysOfWeek array, not Monday.

Related

How to get country specific formatting rules?

I am currently building a workflow for vega lite API and want to parametrize the choice of a locale.
So I want the user to specify her country code by providing a IETF language tag like "us-En" or "fr-FR" and from that I want to obtain the country specific formatting rules (see below for the format I need).
E.g., I am looking for a function, which produces the following output for different country codes:
function getLocaleFormats(countryCode) {
if (countryCode === "de-DE") {
return {
"decimal": ",",
"thousands": ".",
"grouping": [3],
"currency": ["€", ""],
"dateTime": "%a %b %e %X %Y",
"date": "%d.%m.%Y",
"time": "%H:%M:%S",
"periods": ["AM", "PM"],
"days": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
"shortDays": ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
"months": ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],
"shortMonths": ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"]
};
}
}
Any help would be greatly appreciated.
You are looking for the built-in Intl object:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/NumberFormat
On instances of these objects you can call resolvedOptions() to get detailed information about the formatting being used on that locale.
Example:
const nf = new Intl.NumberFormat('en-US');
const df = new Intl.DateTimeFormat('en-US');
const nfOptions = nf.resolvedOptions();
const dfOptions = df.resolvedOptions();
console.dir(nfOptions);
console.dir(dfOptions);
I found the references I need, they are in:
https://unpkg.com/d3-format#1/locale/${countryCode}.json
https://unpkg.com/d3-time-format#1/locale/${countryCode}.json
with country code being the IETF language tag like "us-En".
p.s. I noticed these formatting rules are specified in d3.js as vega lite is build upon d3.js, so I added the d3.js and vega lite tags to the question.

How to show next time slots from the current time

I am trying to show next time slots from the current time.
Table contains the time slots 'time' = 12:00 AM, 10:00 AM, 12:00 PM, 02:00 PM, 05:00 PM, 08:00 PM, 10:00 PM
I just want to show the upcoming time slots from the current time. The time slots remaining for today will show in today array and the next time slots in tomorrow array.
$now = Carbon::now()->format('g:i A');
$time = TimeSlot::where('time', '<', $now)->get();
$data = array('message'=>ResponseMessage::statusResponses(ResponseMessage::_STATUS_DATA_FOUND), 'timeSlots'=>$time, 'current_time'=>$now);
return $this->sendSuccessResponse($data);
Output is :
{
"message": "Data retrieve Successfully",
"timeSlots": [
{
"id": 1,
"time": "12:00 AM"
},
{
"id": 2,
"time": "10:00 AM"
},
{
"id": 3,
"time": "12:00 PM"
},
{
"id": 4,
"time": "02:00 PM"
},
{
"id": 5,
"time": "05:00 PM"
},
{
"id": 6,
"time": "08:00 PM"
},
{
"id": 7,
"time": "10:00 PM"
}
],
"current_time": "5:16 PM",
"status": true
}
Reuired Output will be something like this:
{
"message": "Data retrieve Successfully",
"timeSlots": [
{
"today": [
{
"id": 6,
"time": "08:00 PM"
},
{
"id": 7,
"time": "10:00 PM"
}
],
"tomorrow": [
{
"id": 1,
"time": "12:00 AM"
},
{
"id": 2,
"time": "10:00 AM"
},
{
"id": 3,
"time": "12:00 PM"
},
{
"id": 4,
"time": "02:00 PM"
},
{
"id": 5,
"time": "05:00 PM"
}
],
}
],
"current_time": "5:16 PM",
"status": true
}
Please help me out,
In case you can't modify your table to store info in a more useful way (as suggested in my comment), you can do at the collection level. For this, I'm making use of the map() and partition() collection methods. Given that the first method returns the same collection instance, it allows us to chain the methods.
list($tomorrow, $today) = TimeSlot::all()
// Here we create a new field that will contain a carbon instance of the time
->map(function ($slot) {
$slot['timeTemp'] = Carbon::createFromFormat('g:i A', $slot['time']);
return $slot;
})
// Then we partition the collection using the current time,
// this will return two collections
->partition(function ($slot) {
return $slot['timeTemp'] < now();
});
$timeSlots = [
'today' => $today,
'tomorrow' => $tomorrow,
];
$data = [
'message' => ResponseMessage::statusResponses(ResponseMessage::_STATUS_DATA_FOUND),
'timeSlots' => $timeSlots,
'current_time' => Carbon::now()->format('g:i A'),
];
return $this->sendSuccessResponse($data);
Of course, this will also return the 'timeTemp' value that we inserted in each time slot, but you can ignore them or remove them by mapping through each slot again. Up to you.

Laravel collection sum of columns group by month

I'm working on Laravel project where I need to fetch some data, sum the columns and group the results in M-y (Jan-19) format to show in a monthly bar graph chart.
I was able to successfully get the data sum'ed and grouped but the problem is, for the months without any records, I still want to show up in the graph with a total equals to 0.
This is my current approach:
$data = $this->user->income()
->whereBetween('game_date', ['2019-01-01', '2019-04-30'])
->selectRaw('sum(total_score) as score,
sum(total_stars) as stars,
MONTH(game_date) as month,
DATE_FORMAT(game_date,"%b") as month_name
')
->groupBy('month', 'month_name')
->get();
This gives me the following result (missing months without any records):
[
{
"score": "707",
"stars": "64",
"month": 1,
"month_name": "Jan"
},
{
"score": "200",
"stars": "29",
"month": 3,
"month_name": "Mar"
}
]
And the expected result is including missing months to making visually clear chart as:
[
{
"score": "707",
"stars": "64",
"month": 1,
"month_name": "Jan"
},
{
"score": "0",
"stars": "0",
"month": 2,
"month_name": "Feb"
},
{
"score": "200",
"stars": "29",
"month": 3,
"month_name": "Mar"
},
]
Please note that the ->whereBetween('game_date', []) will aways have dates from start of month and end of month (covering full monthly records).
you have to use COALESCE() function. It's because at the month of Feb you get null at sum(total_score) as score instead of 0. look at
here and here
hop it help

Formatting metrics in Superset / Caravel pivot table

My Superset / Caravel pivot table slice is displaying the metrics (sum of revenue in this case) in scientific notation.
All 4.136578e+08 355190412.0 5.375492e+07 8.226031e+08
How do I display it nicely with thousands separator?
I cant find any options to specify Number Format for Pivot Table visualization type. In contrast, when I create slice using Big Number type, there is option to specify Number Format where it accepts D3 number format. I cant find this for Pivot Table.
you can change it by :-
select the table .
edit the record .
list the sql metrics.
then choose the metric
you can fill the D3 format with +, | +12,345.4321
You may changing number in D3 format, here's some guideline :
{
"decimal": ".",
"thousands": ",",
"grouping": [3],
"currency": ["$", ""],
"dateTime": "%a %b %e %X %Y",
"date": "%m/%d/%Y",
"time": "%H:%M:%S",
"periods": ["AM", "PM"],
"days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
"shortDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
"months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
"shortMonths": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
}
It can be defined in your dataset edit panel,
just like this:
then it can be displayed as you designed.

How to make localization on months / days for D3js?

I am looking for a way to do localization on D3
I have found the values
d3_time_days = [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
d3_time_dayAbbreviations = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ],
d3_time_months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ],
d3_time_monthAbbreviations = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ];
inside D3 but as they are local/privat to D3 i (obviously) cant access them.
Any hints would be great, thanks :)
Update 1:
Seems only a recompile can do the magic - but can't be boughtered - so ended up hard coding the edits in the minified version - shame on me...
Update 2:
Will try to look into how to make D3 accept an "on the fly" localization setting like fx moment.js does it:
moment.lang('da', {
months : "Januar_Februar_Marts_April_Maj_Juni_Juli_August_September_Oktober_November_December".split("_"),
monthsShort : "Jan_Feb_Mar_Apr_Maj_Jun_Jul_Aug_Sep_Okt_Nov_Dec".split("_"),
weekdays : "Søndag_Mandag_Tirsdag_Onsdag_Torsdag_Fredag_Lørdag".split("_"),
weekdaysShort : "Søn_Man_Tir_Ons_Tor_Fre_Lør".split("_"),
weekdaysMin : "Sø_Ma_Ti_On_To_Fr_Lø".split("_"),
ordinal : '%d.',
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
I just had the same issue, and I found the way to fix it without recompiling d3.
https://github.com/mbostock/d3/wiki/Localization
The documentation mentions the function d3.locale, this one builds the functions used for formatting numbers and dates. So if you call it with your own localization rules, you're half way there.
var myFormatters = d3.locale({
"decimal": ".",
"thousands": ",",
"grouping": [3],
"currency": ["$", ""],
"dateTime": "%a %b %e %X %Y",
"date": "%m/%d/%Y",
"time": "%H:%M:%S",
"periods": ["AM", "PM"],
"days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
"shortDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
"months": ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
"shortMonths": ["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"]
});
The next step is to actually tell d3 to use this new formatting functions. So for using the new time formatter do this:
d3.time.format = myFormatters.timeFormat;
Just thought I'd add to #Adrian Salazar's answer as it took me a while to get it right.
If you're doing an axis with 'out-of-the-box' d3 time scale. You can set it to the locale with timeFormat.multi
var localeFormatter = d3.locale({
"decimal": ",",
"thousands": ".",
"grouping": [3],
"currency": ["€", ""],
"dateTime": "%a %b %e %X %Y",
"date": "%d-%m-%Y",
"time": "%H:%M:%S",
"periods": ["AM", "PM"],
"days": ["Zondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrijdag", "Zaterdag"],
"shortDays": ["Zo", "Ma", "Di", "Wo", "Do", "Vr", "Za"],
"months": ["Januari", "Februari", "Maart", "April", "Mei", "Juni", "Juli", "Augustus", "September", "Oktober", "November", "December"],
"shortMonths": ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"]
})
var tickFormat = localeFormatter.timeFormat.multi([
["%H:%M", function(d) { return d.getMinutes(); }],
["%H:%M", function(d) { return d.getHours(); }],
["%a %d", function(d) { return d.getDay() && d.getDate() != 1; }],
["%b %d", function(d) { return d.getDate() != 1; }],
["%B", function(d) { return d.getMonth(); }],
["%Y", function() { return true; }]
]);
axis.tickFormat(tickFormat);
You can create custom d3 time formatters and use moment.js for localization. For example, to create an axis with localized dates:
var x = d3.time.scale();
var myTimeFormatter = function(date) {
return moment(date).format("LL");
};
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.tickFormat(myTimeFormatter);
Then use moment.lang to add support for additional languages and to toggle current language. Refer to http://momentjs.com/docs/#/i18n for specifics.
From the documentation:
D3's implementation is fixed to a locale at compile time based on the $LOCALE environment variable.
In order to localise it to your environment, you need to recompile d3.js (and d3.min.js) on a machine with the locale settings you want. This will replace the strings you're seeing in the source.
With D3 >= 4 I use this to set de_DE as the default locale:
import { formatDefaultLocale } from 'd3-format';
import { timeFormat, timeFormatDefaultLocale } from 'd3-time-format';
import {
timeSecond,
timeMinute,
timeHour,
timeDay,
timeMonth,
timeWeek,
timeYear,
} from 'd3-time';
// set default locale
formatDefaultLocale({
"decimal": ",",
"thousands": ".",
"grouping": [3],
"currency": ["", "\u00a0€"]
});
// set default time locale
timeFormatDefaultLocale({
"dateTime": "%A, der %e. %B %Y, %X",
"date": "%d.%m.%Y",
"time": "%H:%M:%S",
"periods": ["AM", "PM"],
"days": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
"shortDays": ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
"months": ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],
"shortMonths": ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"]
});
let formatMillisecond = timeFormat(".%L");
let formatSecond = timeFormat(":%S");
let formatMinute = timeFormat("%I:%M");
let formatHour = timeFormat("%I %p");
let formatDay = timeFormat("%a %d");
let formatWeek = timeFormat("%b %d");
let formatMonth = timeFormat("%B");
let formatYear = timeFormat("%Y");
function tickFormat (date) {
function multiFormat (date) {
return (timeSecond(date) < date ? formatMillisecond
: timeMinute(date) < date ? formatSecond
: timeHour(date) < date ? formatMinute
: timeDay(date) < date ? formatHour
: timeMonth(date) < date ? (timeWeek(date) < date ? formatDay : formatWeek)
: timeYear(date) < date ? formatMonth
: formatYear)(date);
}
return multiFormat(date);
}
axis.tickFormat(tickFormat);
Multiple Files:
Recompiling the Lib and providing multiple files of 10.000 lines of codes, differing only at 5 lines... is this best practice?
Patch for on the fly changes:
As locale-string are private you can (or rather need to) patch D3.js.
Unfortunately any patched library complicates update processes.
An example of on-the-fly localization is shown at internationalization and localization at runtime
Official Commit:
Mike Bostock reacted quickly an there is a commit on locale-branch by him. It seems to be a first draft, but maybe it is helpful for you.
dsuess
I did this and it worked
var monthss = ['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'];
var x = d3.time.scale()
.range([0, width]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(d3.time.months)
.tickFormat(function(d,i) {
if(i<monthss.length){
return monthss[i];
}
return monthss[i-monthss.length]
});
The if's are because I draw two years. Hope that this helps.

Resources