Couchdb Map function to get the data in between two dates - javascript

I have set of docs in my couchdb here I mentioned one sample doc:
{
"_id": "26",
"_rev": "1-53ac67e9ec4b4ce8ffa9cd609e107aaf",
"customer_name": "Vadilal",
"type": "trip",
"duration": "10 hours 27 mins",
"end_time": "Jan 1, 2014 10:11:00 PM",
"start_time": "Jan 11, 2014 8:46:00 AM",
}
If I pass timestamp(key) from the URL, if it is in between start_time and end_time then i want to get the docs.
Example:
suppose url would be like this
.../trip/_design/trip/_view/trip?key="Jan 10, 2014 8:46:00 AM"
Here I am passing timestamp as Jan 10, 2014 8:46:00 AM so it comes in between start_time and end_time of above mentioned doc, in this case I need fetch the remaining information.
Kindly help to figure out this problem, it would be great help to me.
I have written function like below :
function(doc){
if(doc.type=="trip"){
var startTime=new Date(doc.start_time);
var endTime=new Date(doc.end_time);
emit([startTime.getTime(),endTime.getTime()], doc);
}
And calling URL as below :
../trip/_design/trip/_view/trip?startkey=[1390086890000]&endkey=[1390086890000,{}]
is above one correct according to my requirement???

That is unfortunately not possible. There are two problems with you requirement.
Views are arranged by a key
You could write a view like this to index documents by the start key or the end key respectively.
function(doc){
emit(doc.start_time, doc_id); // amend with end key to index by end key.
}
you can use three parameters in your query:
key - matches an exact key
startkey - matches all documents that are greater or equal to the start key
endkey - matches all documents that are greater or equal to the end key
The sorting problem
Depending on the type your index keys will be sorted either alphabetically or as integers.
So if your view trip is using a start key like this:
.../trip/_design/trip/_view/trip?start_key="Jan 10, 2014 8:46:00 AM"
You could return all values greater or equal to the string "Jan 10, 2014..." which would be true for "Jan 11, 2014" or "Jan 31, 2014" but there would be false positives for "July 22, 2011" or false negatives for "Feb 01, 2014" as F < J.
To solve this issue you will have to convert the start date to something that can be sorted in time order eg:
parse the date to date time and then convert to epoch like How to get time in milliseconds since the unix epoch in Javascript?
convert the date to yyyyMMddHHmmss formate like 20140110084600
Both of these will sort correctly.
Can you solve your problem
Yes, but with a little client side code. Here's the recipe:
create two views trip/by_start_date and trip/by_end_date which return the start and end date as keys respectively. In a way that is sorted as per the second section above.
Get two sets of documents.
Set 1 should return all documents that start before your date: ..._view/by_start_date?endkey=[your_date]
set 2 should return all documents that end after your date: ..._view/by_end_date?startkey=[your_date]
You then have two sets of document ids and the result you were after will be those documents that are in both these sets.
Further optimization
In the above solution you might just get too many values returned to handle. You can further cut it down using CouchDB's ability to key on more than one value. Key by both start and end date like this:
function(doc){
var start_time = some_conversion_function(doc.start_time);
var end_time = some_conversion_function(doc.end_time);
emit([start_time, end_time], doc_id);
}
If you have any more details on the maximum difference between start time and end time you can use this to further reduce the documents in each set. The below example will return the documents that start no later than X days before date and no later than date and end no later than X days after date.
..._view/by_start_date?startkey=[date-X,]&endkey=[date, date+X]
You can apply a similar logic to the by_end_date view.

Related

convert timestamp Date to javaScript date

in fact, I called my java services from AngularJS and I go back an object that contains a date, for example:
{
"Name": "Jhon"
"date": 1465826400000
}
in my service java 1465826400000 date corresponds to Monday, June 13, 2016 14: 00 UTC and in my Javascript code:
var date = new Date (1465826400000);
and it gives 14-06-2016 4:00:00
that means one day lag between the two dates.
someone has an idea
No, it just means you're looking at the result in the local timezone of your browser. If you look at it as a UTC date, it matches:
console.log(new Date (1465826400000).toISOString()); // "2016-06-13T14:00:00.000Z"

Group by Week using Angular, Underscore and Moment js

Need some help please. I am trying to group my click stats by week using underscore and moment.
here is the code:
var groupedByWeekFbCompleted = _.groupBy($scope.facebookObjects, function(item) {
return moment(item.timeclicked,"YYYY-MM-DD").isoWeek();
});
here is a screen shot of the chart it gives me
When I print groupedByWeekFbCompleted to the console this is what I get
The data comes from the DB formatted like this
2016-06-18 14:03:56
I can not figure out what 24, 26, 27, 28 and 29 represent. My hope is to display the first day of the week as a label and then group by that week
If you will take that date string and parse it using moment you will get something like
moment("2016-11-08 14:03:56", "YYYY-MM-DD HH:mm:ss").isoWeek()
// 45
24, 26, 27, 28 and 29 are the week day, and the values are arrays of dates within that week
EDIT
To display a date string on your labels, you can use the .format method to parse the timestamp you get from the moment function, provide it the same format you used, like so:
moment("2016-11-08 14:03:56", "YYYY-MM-DD HH:mm:ss").format("YYYY-MM-DD HH:mm:ss")
// output: "2016-11-08 14:03:56"

Need to read epoch time in certain timezone and then convert it to user timezone

I have 2 webapps, 1 of them on cloud is "master", to which I need to match dates in the 2nd webapp "child".
Master (1st webapp, cloud) is showing date in IST, Asia/Kolkata which it reads from sql machine sitting in EST timezone.
Child (2nd webapp) reads it's data from Elasticsearch where a java feeder picks up the sql data and pushes it to Elasticsearch as it is, without any conversion.
When I try to read this Elasticsearch data in my webapp (child)
...
{
"_index": "log_event_2016-05-05",
"_type": "log_event",
"_id": "65708004",
"_score": null,
"_source": {
"task_name": "kn_cvs_test",
"task_start_time": "2016-05-05T19:05:05.000-07:00",
"task_end_time": "2016-05-05T19:05:06.000-07:00",
"started_by": "Schedule \"10Minutes\"",
"log_datetime": 1462475106000,
"dw_insert_dt": "2016-05-05T16:40:54.000-07:00"
},
"sort": [
1462475106000
]
}, {
"_index": "log_event_2016-05-05",
"_type": "log_event",
"_id": "65708005",
"_score": null,
"_source": {
"task_name": "kn_cvs_test",
"task_start_time": "2016-05-05T18:55:08.000-07:00",
"task_end_time": "2016-05-05T18:55:11.000-07:00",
"started_by": "Schedule \"10Minutes\"",
"log_datetime": 1462474511000,
"dw_insert_dt": "2016-05-05T16:40:54.000-07:00"
},
"sort": [
1462474511000
]
}
...
the dates in my webapp and the cloud does not match. Please correct me if I am wrong. Since Sql is storing dates in EST, "America/New_York", Momentjs should 1st read the data = 1462475106000 in EST and then apply the user timezone which is IST, "Asia/Kolkata". Is this correct?
//Timestamp column in table
//data = 1462475106000
$scope.getMeData = function(data) {
var dFormat = "YYYY-MM-DD hh:mm:ss A";
moment.tz.setDefault("America/New_York");
return moment.tz(data, "Asia/Kolkata").format(dFormat);
}
Note: 1462475106000 is the 1st entry in both table
I am putting up a plunker here.
Please help me figure out what could be going wrong and how can I match dates in both the webapps (taking cloud as reference).
Update
Java feeder runs a sql query to fetch all the needed columns. Here is how log_datetime is fetched. Is this the correct way to fetch?
(task_end_time - to_date('1-1-1970 00:00:00','MM-DD-YYYY HH24:Mi:SS'))*24*3600*1000 AS "log_datetime"
So I am assuming when it fetches data Daylight saving information is not considered and I am missing out this info too. So on UI side i'll check for isDST() and do a +5:00 hrs or +4:00 hrs depending on it, as date in sql is stored in America/New_York. Plunker with UI fix
There's only one Epoch time anywhere at a time. It's an absolute value.
A value that approximates the number of seconds that have elapsed since the Epoch. A Coordinated Universal Time name (specified in terms of seconds (tm_sec), minutes (tm_min), hours (tm_hour), days since January 1 of the year (tm_yday), and calendar year minus 1900 (tm_year)) is related to a time represented as seconds since the Epoch, according to the expression below.
Ref http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_15
Epoch time is measured from the 01-01-1970 00:00:00 UTC. That's an absolute instant in time, it's not relative to timezone as the timezone UTC is in definition of the epoch.
Whenever you see a number for a date such as your example 1462475106000, it should be assumed to be in UTC/GMT. It's not a timezone specific value. Since the time is Unix based number, by epoch definition it is time passed since epoch (in UTC), making it absolute time.
(01-01-1970 00:00:00 UTC)(epoch) + 1462475106000 = Time in UTC
A date in string is a different matter entirely. It should include the timezone offset with the date part. Date part would be considered to be timezone specific value. Adding timezone offset to it would convert it to absolute value in UTC. Without timezone information a string date has no absolute value (Point in time).
2016-05-05T18:55:08.000-07:00 = (2016-05-05T18:55:08.000) + (07:00 hrs) UTC
or
date + timezone offset = date - offset hrs UTC
Databases don't store dates in any timzzone. They store absolute Unix time value. Timezone setting in databases are set so that the output of the query in string is shown in that timezone format. This setting only specifies the output date format not the value. Since the value is absolute it's same timezone independent.
This setting also helps database in determining the timezone of the date value that a user inserts if he misses the timezone offset. If the user tries to insert a string in date column without timezone database would try to default the string to database timezone setting.
So 1462475106000 is a value in UTC as it's Unix time. It's not in EST.
If you need date to be in EST then use the date in string format not in number format as number format is always UTC.
moment.tz.setDefault("America/New_York");//sets the output date format in EST
Above code will have no effect as it's overwritten by moment.tz(data, "Asia/Kolkata")
Now considering the first entry in the first screenshot.
2016-05-06T04:35:06.000+5:30 (IST) = 2016-05-05T11:05:06.000-00:00 (UTC)
Comparing it with the second screenshot, since the time difference between the two is 4 hours, second one should be in +01:30 timezone, if they both are the same values in absolute time.
2016-05-06T12:35:06.000+1:30 = 2016-05-05T11:05:06.000-00:00 (UTC)
However in the child the value is
2016-05-05T19:05:06.000-07:00 = 2016-05-06T02:05:06.000-00:00 (UTC)
Which is not the same value as both above. Interesting fact is that only date part in the child 2016-05-05T19:05:06.000 when added IST offset +05:30would become the date part in second screenshot.
2016-05-06T12:35:06.00 - 2016-05-05T19:05:06.000 = 5:30 (IST offset)
Leaving that aside your Java feeder code to ElasticSearch is probably culprit here.
It's not writing the correct date-timezone combination to ElasticSearch. Try using the overloaded method getDate()
getDate(int columnIndex, Calendar cal)
in JDBC.
Sometimes JDBC driver misses timezone information, causing the date to be stored in default database timezone, using Calendar would cure that.
Same goes for writing dates as well.
void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException
You just need to convert dates from America/New York to Asia/Kolkata (Asia/Calcutta)?
var newYork = moment.tz("date-from-database", "America/New_York");
var calcutta = newYork.clone().tz("Asia/Calcutta");
Example
var newYork = moment.tz("2016-05-06 12:00:00", "America/New_York");
var losAngeles = newYork.clone().tz("America/Los_Angeles");
var london = newYork.clone().tz("Europe/London");
var Kolkata = newYork.clone().tz("Asia/Kolkata");
var dFormat = "YYYY-MM-DD hh:mm:ss A";
console.log(newYork.format(dFormat),losAngeles.format(dFormat),london.format(dFormat),Kolkata.format(dFormat));
Fiddle

Comparing Date objects correctly

I am using a jQuery UI datepicker to show a range of dates that are available to the user. I get the date ranges from an API in the form of
"DateRanges": [
{
"StartDate": "0001-01-01T00:00:00",
"EndDate": "0001-01-01T00:00:00"
}
]
The problem is that I am running a comparison on the dates in the beforeShowDay API mapping function, but when I try to convert these dates into a JavaScript Date object for comparison, the Date() constructor is converting the dates to local time and therefore causing the date to change.
For example, if I use new Date("2014-08-22"); then I would expect a Date object that was set to 8/22/2014 at 12:00 AM but instead it is showing 8/21/2014 at 5:00 PM PST. Therefore my comparison does not work correctly because of the conversion.
What can I do to force the Date() object to not change to local time when making comparisons?
This happens because the parsing logic defaults to the UTC time zone when you do not supply one. To get the expected time, pass a time zone.
new Date("2014-08-22T00:00:00-0700");
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse
This is another tidbit from the docs that might help (depending on how you are generating those dates):
Given a date string of "March 7, 2014", parse assumes a local time zone, but given an ISO format such as "2014-03-07" it will assume a time zone of UTC. Therefore Date objects produced using those strings will represent different moments in time unless the system is set with a local time zone of UTC. This means that two date strings that appear equivalent may result in two different values depending on the format of the string that is being converted (this behavior is changed in ECMAScript ed 6 so that both will be treated as local).
so you could also use:
new Date("September 11, 2014");
and you will get a date in your local tz (for me the output is: "Thu Sep 11 2014 00:00:00 GMT-0500 (CDT)").

Moment js Not returning the right day of the week

I am trying to use Momentjs to return the day of the week (ex. "monday" or "mon", doesn't matter as long as it's the name of the day of the week) for the string number that I stored in the db (ex "3"). For some reason I keep getting Monday returned.
var values = ["3", "06:00", "18:00"];
moment().isoWeekday(values[0]).format('ddd');
//returns "Mon"
I've also tried using moment('3','d').format('ddd')
I've also tried using moment().days('3').format('ddd')
Always returns the same day. Usually Sat or Mon.
try
moment().isoWeekday(parseInt(values[0])).format('ddd');
And in general, store the week day as integer and not string:
var values = [3, "06:00", "18:00"];

Categories

Resources