Best way to sum time in Laravel? - laravel

I have a table called transactions with two relevant fields to my question, _start_timestamp_ and _end_timestamp_. I need to sum the amount of time passed between all transactions where _end_timestamp_ is not null. So, the result must be something like Total Time of Transactions: 1 hour and 18 minutes
I've tried using Carbon, but I don't know how to sum all the lines of the table using it.
foreach($timestampStarts as $timestampStart){
$time = new Carbon($timestampStart->start_timestamp);
$shift_end_time =new Carbon($timestampStart->end_timestamp);
dd($time->diffForHumans($shift_end_time));
}

You can use the MySQL TIMESTAMPDIFF function to calculate the difference:
Transaction::whereNotNull('_end_timestamp_')
->sum(DB::raw('TIMESTAMPDIFF(SECOND, _start_timestamp_, _end_timestamp_)'));
This will give you the total in seconds.

You need to retrieve the total difference in minutes. Add the total difference and retrieve the diff for humans. You can retrieve like below:
$diffForHumans = null;
$nowDate = Carbon::now();
$diffInMinutes = 0;
foreach($timestampStarts as $timestampStart){
if(!empty($timestampStart->end_timestamp)){ // if the end timestamp is not empty
$time = new Carbon($timestampStart->start_timestamp);
$shift_end_time =new Carbon($timestampStart->end_timestamp);
//Adding difference in minutes
$diffInMinutes+= $shift_end_time->diffInMinutes($time);
}
}
$totalDiffForHumans = $now->addMinutes($diffInMinutes)->diffForHumans();

Related

How can I speed up the performance Spring Jpa?

The code
int offset = 0;
int bulkSize = eodFileConfig.getBulkSize(); // sample of 10k
setDateTimeFormat();
//Get total record from Temp table
long max = extQRMerchantTrxHistService.getTotalRecords();
do {
log.debug("[execute] start to write to actual table");
// bulk size represent how many items in a page, offset is the page
Page<ExtensionQRMerchantTrxHistEntity> records = extQRMerchantTrxHistService.findRecordsWithPagination(offset, bulkSize);
List<TransactionHistoryExtEntity> transactions = new ArrayList<>();
for (ExtensionQRMerchantTrxHistEntity tempEntity : records) {
log.debug("Record: {} ", tempEntity);
Date a = new Date();
//Query from T_TRXN_DETAIL_EXT
Date dateTime = sf.parse(tempEntity.getTransactionDate());
List<TransactionHistoryExtEntity> histories =
transactionHistoryInquiryService.retrieveHistoryBasedOnRefNoDateAmt(
tempEntity.getTransactionRefNo(), dateTime, tempEntity.getTransactionAmount());
Date b = new Date();
System.out.println("Query Time: " + Math.abs(a.getTime() - b.getTime()));
Date c = new Date();
TransactionHistoryExtEntity transaction;
if (histories.isEmpty()) {
//Insert record
transaction = setTransactionHistory(Boolean.TRUE, tempEntity, null);
} else {
//Update record
transaction = setTransactionHistory(Boolean.FALSE, tempEntity, histories.get(0));
}
Date d = new Date();
System.out.println("Query Time: " + Math.abs(c.getTime() - d.getTime()));
Date e = new Date();
//transactionHistoryExtRepository.saveAndFlush(transaction);
Date f = new Date();
System.out.println("Query Time: " + Math.abs(e.getTime() - f.getTime()));
//Add to list
transactions.add(transaction);
}
//Save & Update all records
transactionHistoryExtRepository.saveAll(transactions);
offset++;
} while ((long) offset * bulkSize < max);
The query
List<TransactionHistoryExtEntity> findTopByReferenceNumberAndTransactionDateAndAmountOrderByTransactionDateDesc(
String referenceNo, Date transactionDate, BigDecimal amount);
I am a bit new with this spring boot stuff. I am trying to insert/update 50k-100k of records into the table. Running 10k seems fast enough however as the size increases the time it takes for the query part in the inner for loop increases. For a record of 50k with 10k bulksize, the first 10k took about 80 seconds to complete (the entire inner iteration), followed by 472 seconds for the next 10k while the last 10k took 1k+ seconds to process. Can anyone explain what is causing the issue? Also, I cleared my table before executing this, meaning it is empty when I run this.
As a result, I tried different bulksize such as 30k and 50k. At 30k bulksize, which means it will be 2 outer loops, it completes everything at about 38mins, 50k bulksize at about 33 mins whereas 10k at an hour for 50k records. But this would defeat the purpose of having pagination at the start.
So I noticed that the avg time to query spiked after saveAll method. I am not too sure if it is due to the saveAll or the size of the records. Without the inner loop query part, the entire process just takes about 1 mins to complete.
Does anyone have any idea regarding the issue and how I can increase the performance?

Laravel how to add minute to time

I want to make estimate time when user will come. I have 2 variable to save, open and closed time of the store.
$openTime = Carbon::parse($open);
$closedTime = Carbon::parse($closed);
i can get the duration between 2 variable. And i can get duration for each person who come.
$Duration = $startTime->diffInSeconds($endTime);
$perpersonDuration = gmdate("H:i:s", $Duration/$quota);
The question is how to add $perpersonduration to time. In this case i want to add $perpersonduration with $opentime. So it will be like $opentime + $perpersonduration.
Please help
In Carbon there is a method called addMinutes() and you can pass the number of minutes as you won't like this
$openTime = Carbon::now(); // 02:00:00
$closeTime = Carbon::parse($openTime)->addMinutes(30); // 02:30:00

How to count two related dates in Laravel using Query Builder?

I have this list of dates
I want to count the times that the time is higher than 24 hours between each dates in a row... tried with this ..
$tiempo1 = DB::table('incidencia_tiempo')
->whereTime('time', '>', '0000-00-00 24:00:00')
->count();
Beetween time and created at... I would like to count... if beetween the two times the hours are higher than 24 hours then add +1 to the count
I have to make a comparation with created_at and time and I don't know how
Use TIMESTAMPDIFF() to get the time between two datetime,
If you want to count the time high than the created_at 24 hours
$count = DB::table('incidencia_tiempo')
->where(DB::raw('TIMESTAMPDIFF(HOUR, time, created_at)'), '>', 24)
->count();
if you want to count the time difference between two datetimes high than 24 hours:
$count = DB::table('incidencia_tiempo')
->where(DB::raw('ABS(TIMESTAMPDIFF(HOUR, time, created_at))'), '>', 24)
->count();
what is yoiur mean time is higher than 24 hours?
Try This Method for Compare and Count Dates
$text_count = Text::whereBetween('created_at', [$date1, $date2])->count();
first of all you have to run simple query for getting all the data like
$tiempo1 = DB::table('incidencia_tiempo')->get();
and add one loop for this query data
$count = 0;
foreach($tiempo1 as $time) {
$start = new Carbon($time->time);
$end = new Carbon($time->created_at);
$hours = $start->diff($end)->format('%H');
if ($hours > 24){
$count++;
}
}
hope this will help :)

Carbon datetime not working for sum amount laravel

i want to sum amount logs created today in my Repeat table in database i tried followings but not working
$start = (new Carbon('now'))->hour(0)->minute(0)->second(0);
$end = (new Carbon('now'))->hour(23)->minute(59)->second(59);
$data['daily'] = Repeat::where('user_id',Auth::user()->id)->where('created_at',[$start , $end])->sum('amount');
also tried
$start = carbon::today();
$data['daily'] = Repeat::where('user_id',Auth::user()->id)->where('created_at',$start)->sum('amount');
If you want to get today's record by using carbon you can do it as below.
$data['daily'] = Repeat::where('user_id',Auth::user()->id)->whereDate('created_at', Carbon::today())->sum('amount');
you can use Carbon::now() or Carbon::today() but check this amount should be integer or float if it string then sum will be 0(zero)
$data['daily'] = Repeat::where('user_id',Auth::user()->id)->whereDate('created_at', Carbon::now())->sum('amount');```

Google calendar query returns at most 25 entries

I'm trying to delete all calendar entries from today forward. I run a query then call getEntries() on the query result. getEntries() always returns 25 entries (or less if there are fewer than 25 entries on the calendar). Why aren't all the entries returned? I'm expecting about 80 entries.
As a test, I tried running the query, deleting the 25 entries returned, running the query again, deleting again, etc. This works, but there must be a better way.
Below is the Java code that only runs the query once.
CalendarQuery myQuery = new CalendarQuery(feedUrl);
DateFormat dfGoogle = new SimpleDateFormat("yyyy-MM-dd'T00:00:00'");
Date dt = Calendar.getInstance().getTime();
myQuery.setMinimumStartTime(DateTime.parseDateTime(dfGoogle.format(dt)));
// Make the end time far into the future so we delete everything
myQuery.setMaximumStartTime(DateTime.parseDateTime("2099-12-31T23:59:59"));
// Execute the query and get the response
CalendarEventFeed resultFeed = service.query(myQuery, CalendarEventFeed.class);
// !!! This returns 25 (or less if there are fewer than 25 entries on the calendar) !!!
int test = resultFeed.getEntries().size();
// Delete all the entries returned by the query
for (int j = 0; j < resultFeed.getEntries().size(); j++) {
CalendarEventEntry entry = resultFeed.getEntries().get(j);
entry.delete();
}
PS: I've looked at the Data API Developer's Guide and the Google Data API Javadoc. These sites are okay, but not great. Does anyone know of additional Google API documentation?
You can increase the number of results with myQuery.setMaxResults(). There will be a maximum maximum though, so you can make multiple queries ('paged' results) by varying myQuery.setStartIndex().
http://code.google.com/apis/gdata/javadoc/com/google/gdata/client/Query.html#setMaxResults(int)
http://code.google.com/apis/gdata/javadoc/com/google/gdata/client/Query.html#setStartIndex(int)
Based on the answers from Jim Blackler and Chris Kaminski, I enhanced my code to read the query results in pages. I also do the delete as a batch, which should be faster than doing individual deletions.
I'm providing the Java code here in case it is useful to anyone.
CalendarQuery myQuery = new CalendarQuery(feedUrl);
DateFormat dfGoogle = new SimpleDateFormat("yyyy-MM-dd'T00:00:00'");
Date dt = Calendar.getInstance().getTime();
myQuery.setMinimumStartTime(DateTime.parseDateTime(dfGoogle.format(dt)));
// Make the end time far into the future so we delete everything
myQuery.setMaximumStartTime(DateTime.parseDateTime("2099-12-31T23:59:59"));
// Set the maximum number of results to return for the query.
// Note: A GData server may choose to provide fewer results, but will never provide
// more than the requested maximum.
myQuery.setMaxResults(5000);
int startIndex = 1;
int entriesReturned;
List<CalendarEventEntry> allCalEntries = new ArrayList<CalendarEventEntry>();
CalendarEventFeed resultFeed;
// Run our query as many times as necessary to get all the
// Google calendar entries we want
while (true) {
myQuery.setStartIndex(startIndex);
// Execute the query and get the response
resultFeed = service.query(myQuery, CalendarEventFeed.class);
entriesReturned = resultFeed.getEntries().size();
if (entriesReturned == 0)
// We've hit the end of the list
break;
// Add the returned entries to our local list
allCalEntries.addAll(resultFeed.getEntries());
startIndex = startIndex + entriesReturned;
}
// Delete all the entries as a batch delete
CalendarEventFeed batchRequest = new CalendarEventFeed();
for (int i = 0; i < allCalEntries.size(); i++) {
CalendarEventEntry entry = allCalEntries.get(i);
BatchUtils.setBatchId(entry, Integer.toString(i));
BatchUtils.setBatchOperationType(entry, BatchOperationType.DELETE);
batchRequest.getEntries().add(entry);
}
// Get the batch link URL and send the batch request
Link batchLink = resultFeed.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM);
CalendarEventFeed batchResponse = service.batch(new URL(batchLink.getHref()), batchRequest);
// Ensure that all the operations were successful
boolean isSuccess = true;
StringBuffer batchFailureMsg = new StringBuffer("These entries in the batch delete failed:");
for (CalendarEventEntry entry : batchResponse.getEntries()) {
String batchId = BatchUtils.getBatchId(entry);
if (!BatchUtils.isSuccess(entry)) {
isSuccess = false;
BatchStatus status = BatchUtils.getBatchStatus(entry);
batchFailureMsg.append("\nID: " + batchId + " Reason: " + status.getReason());
}
}
if (!isSuccess) {
throw new Exception(batchFailureMsg.toString());
}
There is a small quote on the API page
http://code.google.com/apis/calendar/data/1.0/reference.html#Parameters
Note: The max-results query parameter for Calendar is set to 25 by default,
so that you won't receive an entire
calendar feed by accident. If you want
to receive the entire feed, you can
specify a very large number for
max-results.
So to get all events from a google calendar feed, we do this:
google.calendarurl.com/.../basic?max-results=999999
in the API you can also query with setMaxResults=999999
I got here while searching for a Python solution;
Should anyone be stuck in the same way, the important line is the fourth:
query = gdata.calendar.service.CalendarEventQuery(cal, visibility, projection)
query.start_min = start_date
query.start_max = end_date
query.max_results = 1000
Unfortunately, Google is going to limit the maximum number of queries you can retrieve. This is so as to keep the query governor in their guidelines (HTTP requests not allowed to take more than 30 seconds, for example). They've built their whole architecture around this, so you might as well build the logic as you have.

Resources