I am trying to implement apache beam for a streaming process where I want to calculate the min(), max() value of an item with every registered timestamp.
Eg:
Timestamp
item_count
2021-08-03 01:00:03.22333 UTC
5
2021-08-03 01:00:03.256427 UTC
4
2021-08-03 01:00:03.256497 UTC
7
2021-08-03 01:00:03.256499 UTC
2
Output :
Timestamp
Min
Max
2021-08-03 01:00:03.22333 UTC
5
5
2021-08-03 01:00:03.256427 UTC
4
5
2021-08-03 01:00:03.256497 UTC
4
7
2021-08-03 01:00:03.256499 UTC
2
7
I am not able to figure out how do I fit my use-case to windowing, since for me the frame starts from row 1 and ends with every new I am reading.
Any suggestions how should I approach this?
Thank you
This is not going to be 100% perfect, since there's always going to be some latency and you may get elements in wrong order, but should be good enough.
public interface RollingMinMaxOptions extends PipelineOptions {
#Description("Topic to read from")
#Default.String("projects/pubsub-public-data/topics/taxirides-realtime")
String getTopic();
void setTopic(String value);
}
public static class MinMax extends Combine.CombineFn<Float, KV<Float, Float>, KV<Float, Float>> { //Types: Input, Accum, Output
#Override
public KV<Float, Float> createAccumulator() {
KV<Float, Float> start = KV.of(Float.POSITIVE_INFINITY, 0f);
return start;
}
#Override
public KV<Float, Float> addInput(KV<Float, Float> accumulator, Float input) {
Float max = Math.max(accumulator.getValue(), input);
Float min = Math.min(accumulator.getKey(), input);
return KV.of(min, max);
}
#Override
public KV<Float, Float> mergeAccumulators(Iterable<KV<Float, Float>> accumulators) {
Float max = 0f;
Float min = Float.POSITIVE_INFINITY;
for (KV<Float, Float> kv : accumulators) {
max = Math.max(kv.getValue(), max);
min = Math.min(kv.getKey(), min);
}
return KV.of(min, max);
}
#Override
public KV<Float, Float> extractOutput(KV<Float, Float> accumulator) {
return accumulator;
}
}
public static void main(String[] args) {
RollingMinMaxOptions options = PipelineOptionsFactory.fromArgs(args).withValidation().as(RollingMinMaxOptions.class);
Pipeline p = Pipeline.create(options);
p
.apply("ReadFromPubSub", PubsubIO.readStrings().fromTopic(options.getTopic()))
.apply("Get meter reading", ParDo.of(new DoFn<String, Float>() {
#ProcessElement
public void processElement(ProcessContext c) throws ParseException {
JSONObject json = new JSONObject(c.element());
String rideStatus = json.getString("ride_status");
Float meterReading = json.getFloat("meter_reading");
if (rideStatus.equals("dropoff") && meterReading > 0){
c.output(meterReading);
}
}
})
)
.apply(Window.<Float>into(
new GlobalWindows())
.triggering(Repeatedly.forever(
AfterPane.elementCountAtLeast(1)
)
)
.withTimestampCombiner(TimestampCombiner.LATEST)
.accumulatingFiredPanes()
)
.apply(Combine.globally(new MinMax()))
.apply("Format", ParDo.of(new DoFn<KV<Float, Float>, TableRow>() {
#ProcessElement
public void processElement(ProcessContext c) throws ParseException {
TableRow row = new TableRow();
row.set("min", c.element().getKey());
row.set("max", c.element().getValue());
row.set("timestamp", c.timestamp().toString());
LOG.info(row.toString());
c.output(row);
}
})
);
p.run();
}
If you want the min / max to reset every X time, change it to a FixedWindow of that size
I am trying to group by 2 fields and than count rows of each status.
I am using .NET core 3.1 and newest version of EF.
I am getting an error: The LINQ expression could not be translated. Either rewrite the query in a form that can be translated...
What I investigated so far is, when I get rid off predicate
y.Count(x=>x.Status == "New")
and just leave y.Count() it works fine.
Orders collection is just a mocked list of objects, in my real app it is a table in sql server.
//Rextester.Program.Main is the entry point for your code. Don't change it.
//Microsoft (R) Visual C# Compiler version 2.9.0.63208 (958f2354)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
var orders = new List<Order>();
orders.Add(new Order(){Year = 2020, Status = "New"});
orders.Add(new Order(){Year = 2020, Status = "New"});
orders.Add(new Order(){Year = 2020, Status = "Canceled"});
orders.Add(new Order(){Year = 2020, Status = "Shipped"});
var result = await orders
.GroupBy(x=> new {x.Year, x.Status})
.Select(y => new
{
Year = y.Key.Year,
NewCount = y.Count(x=>x.Status == "New"),
CanceledCount = y.Count(x=>x.Status == "Canceled"),
ShippedCount = y.Count(x=>x.Status == "Shipped")
}).ToListAsync();
}
}
public class Order
{
public int Year {get;set;}
public string Status {get;set;}
}
}
Expected result is:
Year: 2020, NewCount: 2
Year: 2020, CanceledCount : 1
Year: 2020, ShippedCount : 1
What am I doing wrong? How to correct this error to get desired output?
EDIT: This is my playground https://dotnetfiddle.net/v7IYmq
Can you try the following. You are already grouping by Year and Status. Status is part of your key so you can use that to your advantage. Then just count the records using y.Count()
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main(string[] args)
{
var orders = new List<Order>();
orders.Add(new Order(){Year = 2020, Status = "New"});
orders.Add(new Order(){Year = 2020, Status = "New"});
orders.Add(new Order(){Year = 2020, Status = "Canceled"});
orders.Add(new Order(){Year = 2020, Status = "Shipped"});
var result = orders
.GroupBy(x=> new {x.Year, x.Status})
.Select(y => new
{
Year = y.Key.Year,
Status = y.Key.Status,
Count = y.Count()
}).ToList();
foreach (var item in result)
{
Console.WriteLine(string.Format("{0} {1} {2}",item.Year,item.Status, item.Count));
}
}
}
public class Order
{
public int Year {get;set;}
public string Status {get;set;}
}
I`m not found correct way to search with linq2sql in DateTime (DateTime?) fields.
db.Items.Where(x => x.DateTime1.ToString().Contains("2014.08"))
Not work, because in linq2sql create CAST([XXXX.DateTime1] AS NVARCHAR(MAX)) = '04 Aug 2014' NOT 2014.08
I try use custom function mapping, but no result
Why don't you just use the Year and Month property? You should be able to convert the string input into Year and Month number. Then you do something like:
db.Items.Where(x =>
x.DateTime1.Value.Year == 2014
&& x.DateTime1.Value.Month == 8)
It will simply be converted to:
WHERE (2014 = (DATEPART (year, [Extent1].[Date])))
AND (8 = (DATEPART (month, [Extent1].[Date])))
update
You can use SqlFunctions.DatePart and DbFunctions.Right to produce following format yyyy.mm.dd.
db.Items.Where(x =>
(SqlFunctions.DatePart("yyyy", x.DateTime) + "."
+ DbFunctions.Right("0" + SqlFunctions.DatePart("m", x.DateTime1), 2) + "."
+ DbFunctions.Right("0" + SqlFunctions.DatePart("d", x.DateTime1), 2))
.Contains("2014.08"));
Function in MS SQL
CREATE FUNCTION [dbo].[ToString](#P sql_variant)
RETURNS NVARCHAR(20)
AS
BEGIN
IF (sql_variant_property(#P, 'BaseType') = 'datetime')
RETURN CONVERT(NVARCHAR(10), #P, 102) + ' ' + CONVERT(NVARCHAR(8), #P, 108);
RETURN CAST(#P as NVARCHAR(max));
END
Create sql execution Interceptor
public class DbCommandInterceptor : IDbCommandInterceptor
{
public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
if (command.CommandText.IndexOf("CAST") != -1)
{
command.CommandText = command.CommandText.Replace("CAST(", "dbo.ToString(");
command.CommandText = command.CommandText.Replace("] AS nvarchar(max))", "])");
}
}
}
Add Interceptor to DbContext
public class DB : DbContext
{
public DB(): base(#"Data Source=localhost\SQLEXPRESS;Initial Catalog=EFTest")
{
DbInterception.Add(new DbCommandInterceptor ());
}
}
Can anyone give me any recommendations as to how i should approach this properly?
Heres the problem, grab a beer first. My attempt to explain might require a cold one :)
I have a ListView that is being populated via JSON that its being downloaded from a server.
This listview has a pickup_time (String), I am calculating the difference in time between current time and pickup_time
What I am trying to do is load either a green, yellow or red circle image to the assigned pickup_time according to the difference in time I have calculated by using a textView and using textView.setBackgroundColor. in the ListView.
The ListView WAS working properly and displaying information correctly. I've recently only tried to add the green/yellow/red images to the corresponding pickup_time string and this is where its crashing and I need help.
Now for some Codes!
Heres is where I am populating the listView using an AsyncTask. If you notice, I have parse_ready_at(JobsArray, i1); This is where I am caluclating the time difference.
public class Jobs extends ListActivity {
String NEW_JOB = " ";
Vibrator vib;
boolean reloadOnResume;
TextView assigned;
static ProjectDebug LOGCAT = new ProjectDebug();
ProgressDialogManager pDialog = new ProgressDialogManager();
static String JOB, ON_TIME_PERFORMANCE;
// Hashmap for ListView
ArrayList<HashMap<String, String>> contactList;
int PU_time_until_late;
int DEL_time_until_late;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.jobs);
getWindow().setLayout (LayoutParams.FILL_PARENT /* width */ , LayoutParams.WRAP_CONTENT /* height */);
vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
assigned = (TextView) findViewById(R.id.assigned);
RELOAD = true;
Jobs.this.setTitle("My Jobs");
reloadOnResume = false;
VerifyDriverCredentials();
// selecting single ListView item
final ListView lv = getListView();
// Launching new screen on Selecting Single ListItem
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long ide) {
vib.vibrate(40);
// Starting new intent
try { Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
in.putExtra("jobInfo", JOBS.getJSONObject(position).toString());
in.putExtra(pays, JOBS.getJSONObject(position).toString());
in.putExtra(customer_name, JOBS.getJSONObject(position).toString());
in.putExtra(job, JOBS.getJSONObject(position).toString());
in.putExtra(ready_at, JOBS.getJSONObject(position).toString());
in.putExtra(due_by, JOBS.getJSONObject(position).toString());
in.putExtra(customer_reference, JOBS.getJSONObject(position).toString());
in.putExtra(pieces, JOBS.getJSONObject(position).toString());
in.putExtra(weight, JOBS.getJSONObject(position).toString());
in.putExtra(signature_required, JOBS.getJSONObject(position).toString());
in.putExtra(acknowledged, JOBS.getJSONObject(position).toString());
in.putExtra(pickup_actual_datetime, JOBS.getJSONObject(position).toString());
// Pickup Info
in.putExtra(pickup_name, JOBS.getJSONObject(position).toString());
in.putExtra(pickup_addr1, JOBS.getJSONObject(position).toString());
in.putExtra(pickup_city, JOBS.getJSONObject(position).toString());
in.putExtra(pickup_state, JOBS.getJSONObject(position).toString());
in.putExtra(pickup_to_see, JOBS.getJSONObject(position).toString());
in.putExtra(pickup_room, JOBS.getJSONObject(position).toString());
in.putExtra(pickup_phone, JOBS.getJSONObject(position).toString());
in.putExtra(pickup_zip_postal, JOBS.getJSONObject(position).toString());
in.putExtra(pickup_special_instr, JOBS.getJSONObject(position).toString());
// Deliver Info
in.putExtra(deliver_name, JOBS.getJSONObject(position).toString());
in.putExtra(deliver_addr1, JOBS.getJSONObject(position).toString());
in.putExtra(deliver_city, JOBS.getJSONObject(position).toString());
in.putExtra(deliver_state, JOBS.getJSONObject(position).toString());
in.putExtra(deliver_zip_postal, JOBS.getJSONObject(position).toString());
in.putExtra(deliver_to_see, JOBS.getJSONObject(position).toString());
in.putExtra(deliver_room, JOBS.getJSONObject(position).toString());
in.putExtra(deliver_special_instr, JOBS.getJSONObject(position).toString());
in.putExtra(deliver_phone, JOBS.getJSONObject(position).toString());
startActivity(in);
Jobs.this.overridePendingTransition(R.anim.fadein, R.anim.fadeout);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void VerifyDriverCredentials() {
if (jobs_assigned == 0){
assigned.setVisibility(View.VISIBLE);
assigned.setText("You have no jobs assigned");
GetWindowParameters();
}
if (jobs_assigned > 0 && reloadOnResume == false) {
assigned.setVisibility(View.GONE);
new ParseJobs().execute();
}
}
public class ParseJobs extends AsyncTask<Void, Void, Void> {
String DEL_late = "del_late";
String PU_late = " pu_late";
int i1 = 0;
#Override
protected void onPreExecute() {
pDialog.showProgressDialog(Jobs.this, "Performing calculations", "Loading... Please Wait...");
}
#Override
protected Void doInBackground(Void... params) {
contactList = new ArrayList<HashMap<String, String>>();
// looping through All Contacts
try { for (i1 = 0; i1 < JOBS.length(); i1++) {
JobsArray = JOBS.getJSONObject(i1);
JOB = JobsArray.getString(job);
ON_TIME_PERFORMANCE = JobsArray.getString(on_time_performance);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(job, JobsArray.getString(job));
map.put(pays, JobsArray.getString(pays));
map.put(ready_at, JobsArray.getString(ready_at));
map.put(due_by, JobsArray.getString(due_by));
map.put(new_job, JobsArray.getString(new_job));
//map.put(PU_late, Integer.toString(PU_time_until_late));
//map.put(DEL_late, Integer.toString(DEL_time_until_late));
// adding HashList to ArrayList
contactList.add(map);
}
} catch (JSONException e) {
}
parse_ready_at(JobsArray, i1);
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (JOB != null) { assigned.setText(""); }
else { assigned.setText("You have no jobs assigned"); }
GetWindowParameters();
/** Updating parsed JSON data into ListView */
ListAdapter adapter = new SimpleAdapter(Jobs.this, contactList, R.layout.list_item, new String[] { job, pays, ready_at, due_by, new_job, PU_late, DEL_late},
new int[] { R.id.job1, R.id.pays1, R.id.ready_at1, R.id.due_by1, R.id.newjob1, R.id.imageViewReadyAt, R.id.imageViewDueBy });
TextView imageViewReadyAt = (TextView) findViewById(R.id.imageViewReadyAt);
//Change color/answer/etc for textView_5
if ( PU_time_until_late > 60) { // if more than 60 minutes
imageViewReadyAt.setBackgroundResource(R.drawable.notification);
}
if ( PU_time_until_late < 60) { //if less than 60
imageViewReadyAt.setBackgroundResource(R.drawable.green_light);
}
if ( PU_time_until_late < 30) { // if less than 30
imageViewReadyAt.setBackgroundResource(R.drawable.yellow_light);
}
if ( PU_time_until_late < 1) { // if less than 1 minutes
imageViewReadyAt.setBackgroundResource(R.drawable.red_light);
}
setListAdapter(adapter);
pDialog.dismissProgressDialog(Jobs.this);
}
}
public void parse_ready_at(JSONObject JobsArray, int i1) {
String parse_ready_at_ARRAY;
String tracking_Number;
try { for (i1 = 0; i1 < JOBS.length(); i1++) {
JobsArray = JOBS.getJSONObject(i1);
parse_ready_at_ARRAY = JobsArray.getString(ready_at);
tracking_Number = JobsArray.getString(job);
//Example of ready_at String --> "ready_at": "07/25/2012 08:26:00 PM" we split time from date to get time only
SimpleDateFormat parserSDF = new SimpleDateFormat("M/d/yyyy hh:mm:ss a"); // <--- Correct format to read "lastLatitudeUpdate"
try { parserSDF.parse(parse_ready_at_ARRAY);
}
catch (ParseException e) { LOGCAT.DEBUG("JOBS parse_ready_at", "Error parsing tracking number = " + tracking_Number + " ready_at Array = " + parse_ready_at_ARRAY + " Error = " + e.toString()); }
/* ################################################
* #### DISSECTING READY_AT STRING ARRAY ###
* ################################################
*/
String[] dissect_ready_at_DATE_TIME = parse_ready_at_ARRAY.split(" "); // Splitting space between 07/25/2012 and 08:26:00 and PM
String get_ready_at_DATE = String.valueOf(dissect_ready_at_DATE_TIME[0]); // Set at 0 because we want date. 07-25-2012
String get_ready_at_TIME = String.valueOf(dissect_ready_at_DATE_TIME[1]); // Set at 1 because we want time. 08:26:00
String get_ready_at_AMPM = String.valueOf(dissect_ready_at_DATE_TIME[2]); // Set at 2 because we want AM PM.
/* ########################################################
* #### GETTING DATE FROM READY_AT STRING ARRAY ###
* ########################################################
*/
String[] dissect_ready_at_DATE = get_ready_at_DATE.split("/"); // Splitting the / between 07 and 25 and 2012 from 07/25/2012
int get_ready_at_MONTH = Integer.valueOf(dissect_ready_at_DATE[0]); // Set at 0 because we want month. 07
int get_ready_at_DAY = Integer.valueOf(dissect_ready_at_DATE[1]); // Set at 1 because we want day. 25
int get_ready_at_YEAR = Integer.valueOf(dissect_ready_at_DATE[2]); // Set at 2 because we want yeay. 2012
/* ########################################################
* #### GETTING TIME FROM READY_AT STRING ARRAY ###
* ########################################################
*/
String[] dissect_ready_at_TIME = get_ready_at_TIME.split(":"); // Splitting the : between 08 and 26 and 00
int get_ready_at_HOUR = Integer.valueOf(dissect_ready_at_TIME[0]); // Set at 0 because we want hour. 08
int get_ready_at_MINUTE = Integer.valueOf(dissect_ready_at_TIME[1]); // Set at 1 because we want minute. 26
/* ################################################################
* #### CONVERT HOUR FROM READY_AT STRING TO MILITARY TIME ###
* ################################################################
*/
int convert_ready_at_HOUR_to_military = 0; // By default, ready_at String is in 12 hour format. we need to fix it so it is military time.
if (get_ready_at_AMPM.contentEquals("PM")) { // Checking to see if ready_at String has a PM at the end
convert_ready_at_HOUR_to_military = get_ready_at_HOUR + 12; // If it does, add 12 so we can get military time
}
if (get_ready_at_HOUR == 12 & get_ready_at_AMPM.contentEquals("PM") ) {// If hour is set at 12 PM, leave it at 12
convert_ready_at_HOUR_to_military = 12;
}
if (get_ready_at_AMPM.matches("AM")) { // Do Nothing if its AM
convert_ready_at_HOUR_to_military = get_ready_at_HOUR + 0;
}
/* ############################################################
* #### GET THE CURRENT DATE/TIME FROM USERS DEVICE ###
* ############################################################
*/
int current_MONTH = Calendar.getInstance().get(Calendar.MONTH); // Get todays month
int current_DAY = Calendar.getInstance().get(Calendar.DAY_OF_MONTH); // Get todays date
int current_YEAR = Calendar.getInstance().get(Calendar.YEAR); // Get todays year
int current_HOUR = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); // Get todays Hour in military format
int current_MINUTE = Calendar.getInstance().get(Calendar.MINUTE); // Get todays minute
int current_year_FIXUP = current_YEAR - 1900; // example, this year is 2013, subtract 1900 you get 113 which is what Date parameter is requesting
int get_ready_at_year_FIXUP = get_ready_at_YEAR - 1900;
int get_ready_at_MONTH_FIXUP = // * We dont need to fixup current_MONTH because java has already done so
get_ready_at_MONTH - 1; // <-- we subtract 1 because according to parameters, January starts at 0 and December is 11
/*
* How to use Date(int, int, int)
*
*
* *Parameters*
* - year the year, 0 is 1900.
* - month the month, 0 - 11.
* - day the day of the month, 1 - 31
*/
Date ready_at_time = new Date(get_ready_at_year_FIXUP, get_ready_at_MONTH_FIXUP, get_ready_at_DAY); // (2010, June, 20th) = (110, 5, 20) June is 5 instead of 6 because we start
Date current_time = new Date(current_year_FIXUP, current_MONTH, current_DAY); // January at 0 in Java. As for days, it starts at 1 like normal.
int days_between = Days.daysBetween(new DateTime(current_time), new DateTime(ready_at_time)).getDays(); // Get the difference in days of current date and ready_at date
int minutes_difference_in_days_between = days_between * 1440; // 1440 minutes = 1 day. multiply with the date difference of int days_between to get the minutes between those days.
/* ############################################################################
* #### FINAL OUTPUT OF CALCULATING TIMES FROM CURRENT AND READY_AT ###
* ############################################################################
*/
int current_TOTAL_MINUTES = current_HOUR * 60 + current_MINUTE; // Multiply hour by 60 to get the minutes in the hour = RIGHT NOW'S time in minute format
int ready_at_TOTAL_MINUTES = convert_ready_at_HOUR_to_military * 60 + get_ready_at_MINUTE + minutes_difference_in_days_between;
PU_time_until_late = ready_at_TOTAL_MINUTES - current_TOTAL_MINUTES;
LOGCAT.DEBUG("READY_AT " + tracking_Number,"'" + days_between + "'" + " days between today and when the package is scheduled for pickup");
LOGCAT.DEBUG("READY_AT " + tracking_Number, "ready_at String's time = " + parse_ready_at_ARRAY +
" Time now in Minutes = " + current_TOTAL_MINUTES +
" ready_at time in Minutes = " + ready_at_TOTAL_MINUTES +
" Minutes left to complete pickup = " + PU_time_until_late + "\n" + "\n" + "\n" + " ");
}
}
catch (Exception e) {
LOGCAT.DEBUG("Jobs", "Error Splitting/Converting ready_at Time");
}
}
public void GetWindowParameters() {
WindowManager.LayoutParams params = getWindow().getAttributes();
Jobs.this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
Jobs.this.getWindow().setBackgroundDrawableResource(R.drawable.listviewbackground);
/* params.x = 0;
params.height = 480;
params.width = 480;
params.y = 160; */
params.y = 160;
params.height = 600;
params.dimAmount = .70f;
Jobs.this.getWindow().setAttributes(params);
}
Heres the code to get the time difference **public void parse_ready_at()***WARNING* Im pretty sure there is a MUCH easier way to do this but, I'm new and dont know any better lol
public void parse_ready_at(JSONObject JobsArray, int i1) {
String parse_ready_at_ARRAY;
String tracking_Number;
try { for (i1 = 0; i1 < JOBS.length(); i1++) {
JobsArray = JOBS.getJSONObject(i1);
parse_ready_at_ARRAY = JobsArray.getString(ready_at);
tracking_Number = JobsArray.getString(job);
//Example of ready_at String --> "ready_at": "07/25/2012 08:26:00 PM" we split time from date to get time only
SimpleDateFormat parserSDF = new SimpleDateFormat("M/d/yyyy hh:mm:ss a"); // <--- Correct format to read "lastLatitudeUpdate"
try { parserSDF.parse(parse_ready_at_ARRAY);
}
catch (ParseException e) { LOGCAT.DEBUG("JOBS parse_ready_at", "Error parsing tracking number = " + tracking_Number + " ready_at Array = " + parse_ready_at_ARRAY + " Error = " + e.toString()); }
/* ################################################
* #### DISSECTING READY_AT STRING ARRAY ###
* ################################################
*/
String[] dissect_ready_at_DATE_TIME = parse_ready_at_ARRAY.split(" "); // Splitting space between 07/25/2012 and 08:26:00 and PM
String get_ready_at_DATE = String.valueOf(dissect_ready_at_DATE_TIME[0]); // Set at 0 because we want date. 07-25-2012
String get_ready_at_TIME = String.valueOf(dissect_ready_at_DATE_TIME[1]); // Set at 1 because we want time. 08:26:00
String get_ready_at_AMPM = String.valueOf(dissect_ready_at_DATE_TIME[2]); // Set at 2 because we want AM PM.
/* ########################################################
* #### GETTING DATE FROM READY_AT STRING ARRAY ###
* ########################################################
*/
String[] dissect_ready_at_DATE = get_ready_at_DATE.split("/"); // Splitting the / between 07 and 25 and 2012 from 07/25/2012
int get_ready_at_MONTH = Integer.valueOf(dissect_ready_at_DATE[0]); // Set at 0 because we want month. 07
int get_ready_at_DAY = Integer.valueOf(dissect_ready_at_DATE[1]); // Set at 1 because we want day. 25
int get_ready_at_YEAR = Integer.valueOf(dissect_ready_at_DATE[2]); // Set at 2 because we want yeay. 2012
/* ########################################################
* #### GETTING TIME FROM READY_AT STRING ARRAY ###
* ########################################################
*/
String[] dissect_ready_at_TIME = get_ready_at_TIME.split(":"); // Splitting the : between 08 and 26 and 00
int get_ready_at_HOUR = Integer.valueOf(dissect_ready_at_TIME[0]); // Set at 0 because we want hour. 08
int get_ready_at_MINUTE = Integer.valueOf(dissect_ready_at_TIME[1]); // Set at 1 because we want minute. 26
/* ################################################################
* #### CONVERT HOUR FROM READY_AT STRING TO MILITARY TIME ###
* ################################################################
*/
int convert_ready_at_HOUR_to_military = 0; // By default, ready_at String is in 12 hour format. we need to fix it so it is military time.
if (get_ready_at_AMPM.contentEquals("PM")) { // Checking to see if ready_at String has a PM at the end
convert_ready_at_HOUR_to_military = get_ready_at_HOUR + 12; // If it does, add 12 so we can get military time
}
if (get_ready_at_HOUR == 12 & get_ready_at_AMPM.contentEquals("PM") ) {// If hour is set at 12 PM, leave it at 12
convert_ready_at_HOUR_to_military = 12;
}
if (get_ready_at_AMPM.matches("AM")) { // Do Nothing if its AM
convert_ready_at_HOUR_to_military = get_ready_at_HOUR + 0;
}
/* ############################################################
* #### GET THE CURRENT DATE/TIME FROM USERS DEVICE ###
* ############################################################
*/
int current_MONTH = Calendar.getInstance().get(Calendar.MONTH); // Get todays month
int current_DAY = Calendar.getInstance().get(Calendar.DAY_OF_MONTH); // Get todays date
int current_YEAR = Calendar.getInstance().get(Calendar.YEAR); // Get todays year
int current_HOUR = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); // Get todays Hour in military format
int current_MINUTE = Calendar.getInstance().get(Calendar.MINUTE); // Get todays minute
int current_year_FIXUP = current_YEAR - 1900; // example, this year is 2013, subtract 1900 you get 113 which is what Date parameter is requesting
int get_ready_at_year_FIXUP = get_ready_at_YEAR - 1900;
int get_ready_at_MONTH_FIXUP = // * We dont need to fixup current_MONTH because java has already done so
get_ready_at_MONTH - 1; // <-- we subtract 1 because according to parameters, January starts at 0 and December is 11
/*
* How to use Date(int, int, int)
*
*
* *Parameters*
* - year the year, 0 is 1900.
* - month the month, 0 - 11.
* - day the day of the month, 1 - 31
*/
Date ready_at_time = new Date(get_ready_at_year_FIXUP, get_ready_at_MONTH_FIXUP, get_ready_at_DAY); // (2010, June, 20th) = (110, 5, 20) June is 5 instead of 6 because we start
Date current_time = new Date(current_year_FIXUP, current_MONTH, current_DAY); // January at 0 in Java. As for days, it starts at 1 like normal.
int days_between = Days.daysBetween(new DateTime(current_time), new DateTime(ready_at_time)).getDays(); // Get the difference in days of current date and ready_at date
int minutes_difference_in_days_between = days_between * 1440; // 1440 minutes = 1 day. multiply with the date difference of int days_between to get the minutes between those days.
/* ############################################################################
* #### FINAL OUTPUT OF CALCULATING TIMES FROM CURRENT AND READY_AT ###
* ############################################################################
*/
int current_TOTAL_MINUTES = current_HOUR * 60 + current_MINUTE; // Multiply hour by 60 to get the minutes in the hour = RIGHT NOW'S time in minute format
int ready_at_TOTAL_MINUTES = convert_ready_at_HOUR_to_military * 60 + get_ready_at_MINUTE + minutes_difference_in_days_between;
PU_time_until_late = ready_at_TOTAL_MINUTES - current_TOTAL_MINUTES;
LOGCAT.DEBUG("READY_AT " + tracking_Number,"'" + days_between + "'" + " days between today and when the package is scheduled for pickup");
LOGCAT.DEBUG("READY_AT " + tracking_Number, "ready_at String's time = " + parse_ready_at_ARRAY +
" Time now in Minutes = " + current_TOTAL_MINUTES +
" ready_at time in Minutes = " + ready_at_TOTAL_MINUTES +
" Minutes left to complete pickup = " + PU_time_until_late + "\n" + "\n" + "\n" + " ");
}
}
catch (Exception e) {
LOGCAT.DEBUG("Jobs", "Error Splitting/Converting ready_at Time");
}
}
Basically I want those lights to resemble on-time, late etc... not looking to be fed with a golden spoon, just some guidance towards the right direction thats all. Thanks!
EDIT here is my stack trace I forgot to include. I am getting a null pointer exception in onPostExecute. I have declared the textView and already defined it in my onCreate. I believe I have already called it properly in my ListAdapter as well.
if ( PU_ time_until_late < 60) { imageViewReadyAt.setBackgroundColor (R.drawable.green_light); }
EDIT Okay, I figured out why I was getting a null exception when calling imageViewReadyAt Textview. That textview belongs to another XML that belongs in the custom list_item. Still could use some help though.
I'm not sure if it's a bug or what, but I've also had issues modifying the UI from onPostExecute(). To work around it I'll either call a method from there to the main activity and have that work with views, or use a handler and post a message to the proper activity that is using the UI thread.
To make sure I'm on the UI thread I usually use a handler message instead like so:
Handler handlerJobs = new jobsHandler();
public class jobsHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch(msg.arg1) {
case 1:
updateBackgroundColor(msg.arg2);
break;
default:
super.handleMessage(msg);
}
}
}
private void updateBackgroundColor(int dataPassedInMessage) {
if (JOB != null) {
assigned.setText("");
} else {
assigned.setText("You have no jobs assigned");
}
GetWindowParameters();
/** Updating parsed JSON data into ListView */
ListAdapter adapter = new SimpleAdapter(Jobs.this, contactList, R.layout.list_item, new String[] { job, pays, ready_at, due_by, new_job, PU_late, DEL_late},
new int[] { R.id.job1, R.id.pays1, R.id.ready_at1, R.id.due_by1, R.id.newjob1, R.id.imageViewReadyAt, R.id.imageViewDueBy });
TextView imageViewReadyAt = (TextView) findViewById(R.id.imageViewReadyAt);
//Change color/answer/etc for textView_5
if ( PU_time_until_late > 60) {
// if more than 60 minutes
imageViewReadyAt.setBackgroundResource(R.drawable.notification);
}
if ( PU_time_until_late < 60) {
//if less than 60
imageViewReadyAt.setBackgroundResource(R.drawable.green_light);
}
if ( PU_time_until_late < 30) {
// if less than 30
imageViewReadyAt.setBackgroundResource(R.drawable.yellow_light);
}
if ( PU_time_until_late < 1) {
// if less than 1 minutes
imageViewReadyAt.setBackgroundResource(R.drawable.red_light);
}
setListAdapter(adapter);
pDialog.dismissProgressDialog(Jobs.this);
}
}
And then to call it you would use:
#Override
protected void onPostExecute(Void result) {
Message updateBackground = new Message();
updateBackground.arg1 = 1;
updateBackground.arg2 = R.drawable.green_light; //or any int you need to pass
handlerJobs.sendMessage(updateBackground);
}
edit: updated the example so it should work with your code
I think the problem is you are setting background color instead of setting background image. Your image setting code should be as follows e.g. :
imageViewReadyAt.setBackgroundDrawable(R.drawable.green_light);
I am working on a gwt application which involves advanced manipulations with date times: convert from one timezone to another, etc. Gwt has some low level stuff for working with dates but they are too low level for me. Are there any options similar to joda time or threeten for gwt?
You could look at the following options.
http://code.google.com/p/gwt-time/
http://code.google.com/p/goda-time/
http://github.com/mping/gwt-joda-time
This is my DateTimeUtil class
public class DateTimeUtil {
public static String getYear(Date date) {
return DateTimeFormat.getFormat("yyyy").format(date);
}
public static String getMonth(Date date) {
return DateTimeFormat.getFormat("MM").format(date);
}
public static String getDay(Date date) {
return DateTimeFormat.getFormat("dd").format(date);
}
public static String getHour(Date date) {
return DateTimeFormat.getFormat("HH").format(date);
}
public static String getMinute(Date date) {
return DateTimeFormat.getFormat("mm").format(date);
}
public static String getSecond(Date date) {
return DateTimeFormat.getFormat("ss").format(date);
}
// The String year must to have yyyy format
public static Date getDate(String years, String months, String days, String hours, String minutes, String seconds) {
DateTimeFormat dtf = DateTimeFormat.getFormat("yyyy-MM-dd HH:mm:ss");
Date date = dtf.parse(years + "-" + months + "-" + days + " " + hours + ":" + minutes + ":" + seconds);
GWT.log("date parsed " + date);
return date;
}
}