I have the following method:
public StatisticsValues computeStatistics(String Id, Date startDate, Date endDate, UnitTime unitTime){
//Code here
return StatisticsValues;
}
where UnitTime is an enum:
public enum UnitTime {
MINUTE,
HOUR,
DAY,
MONTH,
YEAR
}
An example from my collection in MongoDB could be:
{
"id": "idValue",
"value": true,
"date": "2016-01-21T03:00:00.000Z"
}
For example if the range of dates would be: [2016-03-02,2016-04-02] and the UnitTime would be: HOUR, I'd have to divide the range of dates in 24 ranges.
If in a range of an hour I'd have the followings values: {true, true, false, false}, I could return a numeric value: 0,5.
However, I don't want to divide the ranges in Java, because It'd have a bad performance: if the range of dates covers 10 days, I'd have to make 240 queries!
I'm searching a way throught mongoDB to resolve it.
Thanks.
Related
I'm trying to find out the difference between two timestamps in Hours, Minutes, and Seconds and have managed to chalk out the below code to achieve the same. However, I don't seem to be getting the correct output. Can anyone please tell me where it is that I'm going wrong?
import 'package:intl/intl.dart';
void main() {
String date = '2022-12-05 23:02:20';
var stored =
DateTime.parse(DateFormat('yyyy-mm-dd hh:mm:ss.ms').format(DateTime.parse(date)));
var now = DateTime.now();
var difference = now.difference(stored).inSeconds;
Duration duration = Duration(seconds: difference);
print('VALUE: $stored');
print('CURRENT TIME: $now');
print(stored.runtimeType);
print('HOURS: ${duration.inHours}');
print('MINUTES: ${duration.inMinutes}');
print('SECONDS: ${duration.inSeconds}');
}
This here is the output that I'm getting:
VALUE: 2022-02-05 11:02:20.220
CURRENT TIME: 2022-12-05 23:44:08.827
DateTime
HOURS: 7284
MINUTES: 437081
SECONDS: 26224908
Common mathematics suggests that the difference between 2022-12-05 23:44:08.827 and 2022-02-05 11:02:20.220 should produce 42 minutes and not 437081. Also, this was written on Dartpad
There are a few things wrong:
DateTime.parse(DateFormat('yyyy-mm-dd hh:mm:ss.ms').format(DateTime.parse(date))); makes no sense. You're taking a String representation of a date/time, parsing it with DateTime.parse to get a DateTime object, then using DateFormat to convert that back to a String so that you can call DateTime.parse on it again. Just use DateTime.parse or DateFormat.parse once.
As Ben explained, you're using the wrong DateFormat pattern. MM should be used for the month number; mm should be used for minutes.
.ms in your DateFormat pattern is also wrong; that means minutes and seconds, not milliseconds. You should use S for fractional seconds. But since you're just parsing a date/time string in an ISO format, you don't need DateFormat at all.
var difference = now.difference(stored).inSeconds;
Duration duration = Duration(seconds: difference);
This also doesn't make much sense. now.difference(stored) already returns a Duration object. There's no point in converting a Duration to a number of seconds back to another a Duration unless you're trying to explicitly discard any fractional seconds.
Common mathematics suggests that the difference between 2022-12-05 23:44:08.827 and 2022-02-05 11:02:20.220 should produce 42 minutes and not 437081.
You seem to expect that Duration.inMinutes should return the minutes component of the duration, but inMinutes returns the total number of minutes. For example, Duration(hours: 1, minutes: 2).inMinutes will return 62, not 2. If you instead want the minutes component, you will need to use something like duration.inMinutes.remainder(60). Same thing applies for Duration.inSeconds.
Here is an adjusted version:
void main() {
String date = '2022-12-05 23:02:20';
var stored = DateTime.parse(date);
var now = DateTime.now();
var duration = now.difference(stored);
print('VALUE: $stored');
print('CURRENT TIME: $now');
print(stored.runtimeType);
print('HOURS: ${duration.inHours}');
print('MINUTES: ${duration.inMinutes.remainder(60)}');
print('SECONDS: ${duration.inSeconds.remainder(60)}');
}
which for me outputs:
VALUE: 2022-12-05 23:02:20.000
CURRENT TIME: 2022-12-05 12:12:37.693
DateTime
HOURS: -10
MINUTES: -49
SECONDS: -42
Note that since the above code currently is subtracting a later time from an earlier time, the resulting difference is a negative Duration, so the output might look a little weird.
You should be using MM instead of mm when parsing the date.
Fixed example:
import 'package:intl/intl.dart';
void main() {
String date = '2022-12-05 23:02:20';
var stored =
DateTime.parse(DateFormat('yyyy-MM-dd hh:mm:ss.ms').format(DateTime.parse(date)));
var now = DateTime.now();
var difference = now.difference(stored).inSeconds;
Duration duration = Duration(seconds: difference);
print('VALUE: $stored');
print('CURRENT TIME: $now');
print(stored.runtimeType);
print('HOURS: ${duration.inHours}');
print('MINUTES: ${duration.inMinutes}');
print('SECONDS: ${duration.inSeconds}');
}
Output (13:29 EST timezone):
VALUE: 2022-12-05 11:02:20.220
CURRENT TIME: 2022-12-05 13:29:06.916
DateTime
HOURS: 2
MINUTES: 146
SECONDS: 8806
I used childByAutoId() save the timestamp as an auto-id. I can successfully retrieve the timestamp key that looks like -KJrs03bWbSTXfomqzMW. When I check the key's type, it says AnyObject.
let timestamps = snap.value.allKeys
for timestamp in timestamps {
print(timestamp) // -KJrs03bWbSTXfomqzMW
if let t = timestamp as? NSTimeInterval {
print(NSDate(timeIntervalSince1970: t/1000))
print("true")
} else {
print("false")
}
}
However, it goes into false bit.
What am I doing wrong? What is the proper way of converting Firebase timestamps to NSDate?
PS:
I remember I read Firebase allows for a global timing for the items with this kind of timestamp. Is there a way that would enable me to get human-readable version of the time, such as 30mins ago, 5 hrs ago directly working with Firebase or should I use NSDateFormatter?
The node looks like:
- -KJrs03bWbSTXfomqzMW
- "key1": "val"
- "key2": "val"
I am trying to write formula in my domain class which helps me in creating criteria.
class MyClass {
//some fields
Date appointmentTime
String ddmmyy
int year
int month
int day
static transients = [
'ddmmyy',
'year',
'month',
'day'
]
static mapping= {
ddmmyy formula('DATE_FORMAT(appointmentTime)')
year formula('YEAR(appointmentTime)')
month formula('MONTH(appointmentTime)')
day formula('DAYOFMONTH(appointmentTime)')
}
}
Whenever I am trying to use this fields in my criteria it throws error i.e. can not resolve property 'ddmmyy' of 'myClass'.
MyCriteria is:
Date myDate = Calender.instance.time
def results = MyClass.createcriteria().list{
lt('appointmentTime', date+1)
ge('appointmentTime', date)
projections {
groupProperty('ddmmyy')
count('id')
}
}
Any idea why I am getting an exception for this?
You need to make these fields non transient to use in criteria. See reference document
http://gorm.grails.org/6.1.x/hibernate/manual/#derivedProperties
I have a domain class (minified) as :-
class Expense {
Date dateOfExpense
int amount
}
I am trying to get sum of amount grouped by week/month/ year of expense date.
Referring to 'sqlGroupProjection' method in grails doc http://grails.org/doc/latest/guide/GORM.html,
I tried using following code:-
def results = c {
between("dateOfExpense", fromDate, toDate)
projections {
sqlGroupProjection 'dateOfExpense,sum(amount) as summed',
'MONTH(dateOfExpense)',['date','summed'],[DATE,NUMBER]
}
}
Throws exception:
No such property: DATE for class: grails.orm.HibernateCriteriaBuilder. Stacktrace follows:
Message: No such property: DATE for class: grails.orm.HibernateCriteriaBuilder
Please suggest an approach using sqlGroupProjection method
Create three new numeric fields each for week,month and year in the domain class. These fields won't be mapped to column in the table.
Provide static mapping for the three fields.
static mapping = {
//provide the exact column name of the date field
week formula('WEEK(DATE_OF_EXPENSE)')
month formula('MONTH(DATE_OF_EXPENSE)')
year formula ('YEAR(DATE_OF_EXPENSE)')
}
Now we can group by desired field using
def results = c.list {
between("dateOfExpense", fromDate, toDate)
projections {
switch(groupBy){
case "week":
groupProperty('year')
groupProperty('month')
groupProperty('week')
break;
case "month"
groupProperty('year')
groupProperty('month')
break;
case "year":
groupProperty('year')
break;
}
sum('amount')
}
}
Instead of this
static mapping = {
week formula('WEEK(DATE_OF_EXPENSE)') //provide the exact column name of the date field
month formula('MONTH(DATE_OF_EXPENSE)')
year formula ('YEAR(DATE_OF_EXPENSE)')
}
try this
static mapping = {
week formula: 'WEEK(DATE)'
month formula: 'MONTH(DATE)'
year formula: 'YEAR(DATE)'
}
Try something like
sqlGroupProjection 'MONTH(dateOfExpense) as month, sum(amount) as summed',
'month',['month','summed'],[NUMBER,NUMBER]
This sqlGroupProjection method seems to be poorly supported. Use
def results = c.list {
between("dateOfExpense", fromDate, toDate)
projections {
groupProperty('dateOfExpense')
sum('amount')
}
}
will produce the deserved outcome.
If you want group by the month of the date, see Grails group by date (It totally outweight my answer, actually. But I reach the same solution after trying your code for a long time.)
I need to check a difference between a given date and current date is less than 365days?
i tried some thing like this.
System.TimeSpan diff = DateTime.UtcNow.Subtract((DateTime)customer.LastValidationDate);
result = (diff.Days < 1);
this doesn't seem to work correct for few dates.
i need to achieve:
if given date and current date difference is less-than or equal to 1 year (365 days) return true
else return false.
try this found at stackoverflow
public static int MonthDifference(this DateTime lValue, DateTime rValue)
{
return (lValue.Month - rValue.Month) + 12 * (lValue.Year - rValue.Year);
}