How to make a field of objects - c#

The field Day[] calendar = new Day[365]; contains the class Day. As the teacher wanted.
But I don't know how to make my method AddRecord to save in this field. I use
hw.Add(new Homework(Convert.ToDateTime(part), parts[1], parts[2]));
to add it to List. But I need to save the data to the Day[] calendar = new Day[365]; I just don't know how.
Class Calendar
class Calendar
{
Day d = new Day();
List<Homework> hw;
Day[] calendar = new Day[365];
//Day[0] = (Convert.ToDateTime("9.3.2008 16:05"), "M", "text"));
public Calendar()
{
hw = d.GetList();
}
public void AddRecord(string line)
{
string[] parts = line.Split(' ');
string part = parts[0] + " " + parts[1];
hw.Add(new Homework(Convert.ToDateTime(part), parts[1], parts[2]));
}
class Day
class Day
{
List<Homework> hw = new List<Homework>();
public List<Homework> GetList()
{
hw = new List<Homework>();
string datum = "29.5.2005 16:55"; //!
hw.Add(new Homework(Convert.ToDateTime(datum), "INF", "THREE"));// !
return hw;
}
}
class Homework
class Homework
{
public DateTime dt; }
public string subject;
public string content;
public Homework(DateTime dt, string subject, string content)
{
String.Format("{0:d.m.yyyy HH:mm}", dt);
this.dt = dt;
this.subject = subject;
this.content = content;
}
}

If I understand what you are trying to accomplish; you want to add the Homeworkrecord to its corresponding Day that is held by the Calendar object.
So first, we need to get the day:
DateTime dataDate = Convert.ToDateTime(part); //Or something
Day dueDate = calendar.FirstOrDefault(d => d.Date = dataDate);
Note that this probably won't work first time, as you need to compare just the day. If you created the Day object with a different time than the Homework item had, the forthcoming null check will fail. I'll leave that comparison as an exercise to you, but feel free to leave a comment if you can't figure it out.
Then we need to give it the homework item:
if (dueDate != null) //Check if we found the date!
dueDate.AddHomeworkItem(new Homework(dataDate, parts[2], parts[3]));
else
throw new Exception("Date not found; invalid data read"); //Or something
//Failing silently is usually bad
Of course, that requires a method in the Day class:
public void AddHomeworkItem(Homework item)
{
hw.Add(item);
}
Thats it! A couple things I noticed while looking at your code:
You have a Day and List<Homework> in your Calendar class. You shouldn't need either of them. The Day[] is sufficient from what I can see.
It looked like you reused parts[1] in your add function. I doubt you want the date to be part of the subect! I fixed it in my code.
Your Day class pre-populates its Homework list with a nonsensical item. You probably need to remove that.

Related

Sort a List<String> that includes date values by date

I am working on a time clock program and I am having an issue getting my time punches to be in the correct order. The dates are in order, but the list.Sort() is putting the times out of order. It is sorting it like a string, which make sense because it is a string. 3:41PM is sorted before 7:20AM because 3 is before 7. See example:
12/17/2018 3:41:00 PM Clock Out Yes BB
12/17/2018 7:20:00 AM Clock In NO Not Needed
I am not sure how to accomplish this because of the information I am dumping into the list.
while (reader.Read())
{
timeClockDataList.Add(reader["Punch"].ToString() + "%" + reader["PunchType"].ToString() + "%" + reader["NeedsApproval"].ToString() + "%" + reader["Approval"].ToString());
}
I am putting the "%" in there so I can split the string at the % later to populate the time card with the punch time, type of punch, approval needed, and approval.
My question is how to sort this string by the Date AND Time?
EDIT
while (reader.Read())
{
timeClockDataList.Add(new ClockData
{
Punch = DateTime.Parse(reader["Punch"].ToString()),
PunchType = reader["PunchType"].ToString(),
NeedsApproval = reader["NeedsApproval"].ToString(),
Approval = reader["Approval"].ToString(),
});
//***This is the old code that makes one long string***
//timeClockDataList.Add(reader["Punch"].ToString() + "%" + ToString() + +
}
timeClockDataList.OrderBy(x => x.Punch);
//***This is the old code that would sort the list string***
//timeClockDataList.Sort();
using (StreamWriter writer = new StreamWriter(filePath, true))
{
for (int _i = 0; _i < timeClockDataList.Count; ++_i)
{
punch = timeClockDataList[_i].Punch.ToString();
punchType = timeClockDataList[_i].PunchType;
needsApproval = timeClockDataList[_i].NeedsApproval;
approval = timeClockDataList[_i].Approval;
writer.WriteLine(String.Format("{0,-5}{1,-30}{2,-20}{3,-11}{4,-15}", " ", punch, punchType, needsApproval, approval));
punch = null;
punchType = null;
needsApproval = null;
approval = null;
}
}
timeClockDataList is the wrong type. When everything is one big string then you don't have data, you just have one big string.
Make a custom object to store your data. For example:
class ClockData
{
public DateTime Punch { get; set; }
public string PunchType { get; set; }
// etc.
}
Read your data into a list of that class:
while (reader.Read())
{
timeClockDataList.Add(new ClockData
{
Punch = DateTime.Parse(reader["Punch"].ToString()),
PunchType = reader["PunchType"].ToString(),
// etc.
});
}
Now you have actual data, which can be manipulated/sorted/etc. easily:
timeClockDataList.OrderBy(x => x.Punch)
You may also want to throw in some error checking when populating it, use TryParseExact for the DateTime, etc. There are a variety of improvements you can make. Eventually, when you want to display the data, that's when you output it as a string. (You can make that very simple by overriding .ToString() on the custom class.)

How do I render a DateTime object after it has been passed through JSON? [duplicate]

I have a controller action that effectively simply returns a JsonResult of my model. So, in my method I have something like the following:
return new JsonResult(myModel);
This works well, except for one problem. There is a date property in the model and this appears to be returned in the Json result like so:
"\/Date(1239018869048)\/"
How should I be dealing with dates so they are returned in the format I require? Or how do I handle this format above in script?
Just to expand on casperOne's answer.
The JSON spec does not account for Date values. MS had to make a call, and the path they chose was to exploit a little trick in the javascript representation of strings: the string literal "/" is the same as "\/", and a string literal will never get serialized to "\/" (even "\/" must be mapped to "\\/").
See http://msdn.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_topic2 for a better explanation (scroll down to "From JavaScript Literals to JSON")
One of the sore points of JSON is the
lack of a date/time literal. Many
people are surprised and disappointed
to learn this when they first
encounter JSON. The simple explanation
(consoling or not) for the absence of
a date/time literal is that JavaScript
never had one either: The support for
date and time values in JavaScript is
entirely provided through the Date
object. Most applications using JSON
as a data format, therefore, generally
tend to use either a string or a
number to express date and time
values. If a string is used, you can
generally expect it to be in the ISO
8601 format. If a number is used,
instead, then the value is usually
taken to mean the number of
milliseconds in Universal Coordinated
Time (UTC) since epoch, where epoch is
defined as midnight January 1, 1970
(UTC). Again, this is a mere
convention and not part of the JSON
standard. If you are exchanging data
with another application, you will
need to check its documentation to see
how it encodes date and time values
within a JSON literal. For example,
Microsoft's ASP.NET AJAX uses neither
of the described conventions. Rather,
it encodes .NET DateTime values as a
JSON string, where the content of the
string is /Date(ticks)/ and where
ticks represents milliseconds since
epoch (UTC). So November 29, 1989,
4:55:30 AM, in UTC is encoded as
"\/Date(628318530718)\/".
A solution would be to just parse it out:
value = new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10));
However I've heard that there is a setting somewhere to get the serializer to output DateTime objects with the new Date(xxx) syntax. I'll try to dig that out.
The second parameter of JSON.parse() accepts a reviver function where prescribes how the value originally produced by, before being returned.
Here is an example for date:
var parsed = JSON.parse(data, function(key, value) {
if (typeof value === 'string') {
var d = /\/Date\((\d*)\)\//.exec(value);
return (d) ? new Date(+d[1]) : value;
}
return value;
});
See the docs of JSON.parse()
Here's my solution in Javascript - very much like JPot's, but shorter (and possibly a tiny bit faster):
value = new Date(parseInt(value.substr(6)));
"value.substr(6)" takes out the "/Date(" part, and the parseInt function ignores the non-number characters that occur at the end.
EDIT: I have intentionally left out the radix (the 2nd argument to parseInt); see my comment below. Also, please note that ISO-8601 dates are preferred over this old format -- so this format generally shouldn't be used for new development.
For ISO-8601 formatted JSON dates, just pass the string into the Date constructor:
var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
There are quite a bit of answers to handle it client side, but you can change the output server side if you desired.
There are a few ways to approach this, I'll start with the basics. You'll have to subclass the JsonResult class and override the ExecuteResult method. From there you can take a few different approaches to change the serialization.
Approach 1:
The default implementation uses the JsonScriptSerializer. If you take a look at the documentation, you can use the RegisterConverters method to add custom JavaScriptConverters. There are a few problems with this though: The JavaScriptConverter serializes to a dictionary, that is it takes an object and serializes to a Json dictionary. In order to make the object serialize to a string it requires a bit of hackery, see post. This particular hack will also escape the string.
public class CustomJsonResult : JsonResult
{
private const string _dateFormat = "yyyy-MM-dd HH:mm:ss";
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
if (!String.IsNullOrEmpty(ContentType))
{
response.ContentType = ContentType;
}
else
{
response.ContentType = "application/json";
}
if (ContentEncoding != null)
{
response.ContentEncoding = ContentEncoding;
}
if (Data != null)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
// Use your custom JavaScriptConverter subclass here.
serializer.RegisterConverters(new JavascriptConverter[] { new CustomConverter });
response.Write(serializer.Serialize(Data));
}
}
}
Approach 2 (recommended):
The second approach is to start with the overridden JsonResult and go with another Json serializer, in my case the Json.NET serializer. This doesn't require the hackery of approach 1. Here is my implementation of the JsonResult subclass:
public class CustomJsonResult : JsonResult
{
private const string _dateFormat = "yyyy-MM-dd HH:mm:ss";
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
HttpResponseBase response = context.HttpContext.Response;
if (!String.IsNullOrEmpty(ContentType))
{
response.ContentType = ContentType;
}
else
{
response.ContentType = "application/json";
}
if (ContentEncoding != null)
{
response.ContentEncoding = ContentEncoding;
}
if (Data != null)
{
// Using Json.NET serializer
var isoConvert = new IsoDateTimeConverter();
isoConvert.DateTimeFormat = _dateFormat;
response.Write(JsonConvert.SerializeObject(Data, isoConvert));
}
}
}
Usage Example:
[HttpGet]
public ActionResult Index() {
return new CustomJsonResult { Data = new { users=db.Users.ToList(); } };
}
Additional credits:
James Newton-King
Moment.js is an extensive datetime library that also supports this. http://momentjs.com/docs/#/parsing/asp-net-json-dates/
ex: moment("/Date(1198908717056-0700)/")
It might help. plunker output
I found that creating a new JsonResult and returning that is unsatisfactory - having to replace all calls to return Json(obj) with return new MyJsonResult { Data = obj } is a pain.
So I figured, why not just hijack the JsonResult using an ActionFilter:
public class JsonNetFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Result is JsonResult == false)
{
return;
}
filterContext.Result = new JsonNetResult(
(JsonResult)filterContext.Result);
}
private class JsonNetResult : JsonResult
{
public JsonNetResult(JsonResult jsonResult)
{
this.ContentEncoding = jsonResult.ContentEncoding;
this.ContentType = jsonResult.ContentType;
this.Data = jsonResult.Data;
this.JsonRequestBehavior = jsonResult.JsonRequestBehavior;
this.MaxJsonLength = jsonResult.MaxJsonLength;
this.RecursionLimit = jsonResult.RecursionLimit;
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
var isMethodGet = string.Equals(
context.HttpContext.Request.HttpMethod,
"GET",
StringComparison.OrdinalIgnoreCase);
if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet
&& isMethodGet)
{
throw new InvalidOperationException(
"GET not allowed! Change JsonRequestBehavior to AllowGet.");
}
var response = context.HttpContext.Response;
response.ContentType = string.IsNullOrEmpty(this.ContentType)
? "application/json"
: this.ContentType;
if (this.ContentEncoding != null)
{
response.ContentEncoding = this.ContentEncoding;
}
if (this.Data != null)
{
response.Write(JsonConvert.SerializeObject(this.Data));
}
}
}
}
This can be applied to any method returning a JsonResult to use JSON.Net instead:
[JsonNetFilter]
public ActionResult GetJson()
{
return Json(new { hello = new Date(2015, 03, 09) }, JsonRequestBehavior.AllowGet)
}
which will respond with
{"hello":"2015-03-09T00:00:00+00:00"}
as desired!
You can, if you don't mind calling the is comparison at every request, add this to your FilterConfig:
// ...
filters.Add(new JsonNetFilterAttribute());
and all of your JSON will now be serialized with JSON.Net instead of the built-in JavaScriptSerializer.
Using jQuery to auto-convert dates with $.parseJSON
Note: this answer provides a jQuery extension that adds automatic ISO and .net date format support.
Since you're using Asp.net MVC I suspect you're using jQuery on the client side. I suggest you read this blog post that has code how to use $.parseJSON to automatically convert dates for you.
Code supports Asp.net formatted dates like the ones you mentioned as well as ISO formatted dates. All dates will be automatically formatted for you by using $.parseJSON().
Ajax communication between the client and the server often involves data in JSON format. While JSON works well for strings, numbers and Booleans it can pose some difficulties for dates due to the way ASP.NET serializes them. As it doesn't have any special representation for dates, they are serialized as plain strings.
As a solution the default serialization mechanism of ASP.NET Web Forms and MVC serializes dates in a special form - /Date(ticks)/- where ticks is the number of milliseconds since 1 January 1970.
This problem can be solved in 2 ways:
client side
Convert the received date string into a number and create a date object using the constructor of the date class with the ticks as parameter.
function ToJavaScriptDate(value) {
var pattern = /Date\(([^)]+)\)/;
var results = pattern.exec(value);
var dt = new Date(parseFloat(results[1]));
return (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear();
}
server side
The previous solution uses a client side script to convert the date to a JavaScript Date object. You can also use server side code that serializes .NET DateTime instances in the format of your choice.
To accomplish this task you need to create your own ActionResult and then serialize the data the way you want.
reference :
http://www.developer.com/net/dealing-with-json-dates-in-asp.net-mvc.html
I had the same problem and instead of returning the actual date value I just used ToString("dd MMM yyyy") on it. Then in my javascript I used new Date(datevalue), where datevalue may be "01 Jan 2009".
See this thread:
http://forums.asp.net/p/1038457/1441866.aspx#1441866
Basically, while the Date() format is valid javascript, it is NOT valid JSON (there is a difference). If you want the old format, you will probably have to create a facade and transform the value yourself, or find a way to get at the serializer for your type in the JsonResult and have it use a custom format for dates.
Not the most elegant way but this worked for me:
var ms = date.substring(6, date.length - 2);
var newDate = formatDate(ms);
function formatDate(ms) {
var date = new Date(parseInt(ms));
var hour = date.getHours();
var mins = date.getMinutes() + '';
var time = "AM";
// find time
if (hour >= 12) {
time = "PM";
}
// fix hours format
if (hour > 12) {
hour -= 12;
}
else if (hour == 0) {
hour = 12;
}
// fix minutes format
if (mins.length == 1) {
mins = "0" + mins;
}
// return formatted date time string
return date.getMonth() + 1 + "/" + date.getDate() + "/" + date.getFullYear() + " " + hour + ":" + mins + " " + time;
}
I have been working on a solution to this issue as none of the above answers really helped me. I am working with the jquery week calendar and needed my dates to have time zone information on the server and locally on the page. After quite a bit of digging around, I figured out a solution that may help others.
I am using asp.net 3.5, vs 2008, asp.net MVC 2, and jquery week calendar,
First, I am using a library written by Steven Levithan that helps with dealing with dates on the client side, Steven Levithan's date library. The isoUtcDateTime format is perfect for what I needed. In my jquery AJAX call I use the format function provided with the library with the isoUtcDateTime format and when the ajax call hits my action method, the datetime Kind is set to local and reflects the server time.
When I send dates to my page via AJAX, I send them as text strings by formatting the dates using "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'zzzz". This format is easily converted client side using
var myDate = new Date(myReceivedDate);
Here is my complete solution minus Steve Levithan's source, which you can download:
Controller:
public class HomeController : Controller
{
public const string DATE_FORMAT = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'zzzz";
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
return View();
}
public JsonResult GetData()
{
DateTime myDate = DateTime.Now.ToLocalTime();
return new JsonResult { Data = new { myDate = myDate.ToString(DATE_FORMAT) } };
}
public JsonResult ReceiveData(DateTime myDate)
{
return new JsonResult { Data = new { myDate = myDate.ToString(DATE_FORMAT) } };
}
}
Javascript:
<script type="text/javascript">
function getData() {
$.ajax({
url: "/Home/GetData",
type: "POST",
cache: "false",
dataType: "json",
success: function(data) {
alert(data.myDate);
var newDate = cleanDate(data.myDate);
alert(newDate);
sendData(newDate);
}
});
}
function cleanDate(d) {
if (typeof d == 'string') {
return new Date(d) || Date.parse(d) || new Date(parseInt(d));
}
if (typeof d == 'number') {
return new Date(d);
}
return d;
}
function sendData(newDate) {
$.ajax({
url: "/Home/ReceiveData",
type: "POST",
cache: "false",
dataType: "json",
data:
{
myDate: newDate.format("isoUtcDateTime")
},
success: function(data) {
alert(data.myDate);
var newDate = cleanDate(data.myDate);
alert(newDate);
}
});
}
// bind myButton click event to call getData
$(document).ready(function() {
$('input#myButton').bind('click', getData);
});
</script>
I hope this quick example helps out others in the same situation I was in. At this time it seems to work very well with the Microsoft JSON Serialization and keeps my dates correct across timezones.
The better way to handle dates in knockoutjs is to use moment library and handle dates like boss. You can easily deal with dates like /Date(-62135578800000)/. No need to bother of how your serialize date in controller.
function jsonToDate(date,format) {
return moment(date).format(format);
}
use it like
var formattedDate = jsonToDate(date,'MM/DD/YYYY')
momentjs supports lots of date time formats and utility functions on dates.
Format the date within the query.
var _myModel = from _m in model.ModelSearch(word)
select new { date = ((DateTime)_m.Date).ToShortDateString() };
The only problem with this solution is that you won't get any results if ANY of the date values are null. To get around this you could either put conditional statements in your query BEFORE you select the date that ignores date nulls or you could set up a query to get all the results and then loop through all of that info using a foreach loop and assign a value to all dates that are null BEFORE you do your SELECT new.
Example of both:
var _test = from _t in adc.ItemSearchTest(word)
where _t.Date != null
select new { date = ((DateTime)_t.Date).ToShortDateString() };
The second option requires another query entirely so you can assign values to all nulls. This and the foreach loop would have to be BEFORE your query that selects the values.
var _testA = from _t in adc.ItemSearchTest(word)
select _i;
foreach (var detail in _testA)
{
if (detail.Date== null)
{
detail.Date= Convert.ToDateTime("1/1/0001");
}
}
Just an idea which I found easier than all of the javascript examples.
You can use this method:
String.prototype.jsonToDate = function(){
try{
var date;
eval(("date = new " + this).replace(/\//g,''));
return date;
}
catch(e){
return new Date(0);
}
};
I found this to be the easiest way to change it server side.
using System.Collections.Generic;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
namespace Website
{
/// <summary>
/// This is like MVC5's JsonResult but it uses CamelCase and date formatting.
/// </summary>
public class MyJsonResult : ContentResult
{
private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Converters = new List<JsonConverter> { new StringEnumConverter() }
};
public FindersJsonResult(object obj)
{
this.Content = JsonConvert.SerializeObject(obj, Settings);
this.ContentType = "application/json";
}
}
}
Here's some JavaScript code I wrote which sets an <input type="date"> value from a date passed from ASP.NET MVC.
var setDate = function(id, d) {
if (d !== undefined && d !== null) {
var date = new Date(parseInt(d.replace("/Date(", "").replace(")/", ""), 10));
var day = ('0' + date.getDate()).slice(-2);
var month = ('0' + (date.getMonth() + 1)).slice(-2);
var parsedDate = date.getFullYear() + "-" + (month) + "-" + (day);
$(id).val(parsedDate);
}
};
You call this function like so:
setDate('#productCommissionStartDate', data.commissionStartDate);
Where commissionStartDate is the JSON date passed by MVC.
add jquery ui plugin in your page.
function JsonDateFormate(dateFormate, jsonDateTime) {
return $.datepicker.formatDate(dateFormate, eval('new ' + jsonDateTime.slice(1, -1)));
};
Not for nothing, but there is another way. First, construct your LINQ query. Then, construct a query of the Enumerated result and apply whatever type of formatting works for you.
var query = from t in db.Table select new { t.DateField };
var result = from c in query.AsEnumerable() select new { c.DateField.toString("dd MMM yyy") };
I have to say, the extra step is annoying, but it works nicely.
What worked for me was to create a viewmodel that contained the date property as a string. Assigning the DateTime property from the domain model and calling the .ToString() on the date property while assigning the value to the viewmodel.
A JSON result from an MVC action method will return the date in a format compatible with the view.
View Model
public class TransactionsViewModel
{
public string DateInitiated { get; set; }
public string DateCompleted { get; set; }
}
Domain Model
public class Transaction{
public DateTime? DateInitiated {get; set;}
public DateTime? DateCompleted {get; set;}
}
Controller Action Method
public JsonResult GetTransactions(){
var transactions = _transactionsRepository.All;
var model = new List<TransactionsViewModel>();
foreach (var transaction in transactions)
{
var item = new TransactionsViewModel
{
...............
DateInitiated = transaction.DateInitiated.ToString(),
DateCompleted = transaction.DateCompleted.ToString(),
};
model.Add(item);
}
return Json(model, JsonRequestBehavior.AllowGet);
}
Override the controllers Json/JsonResult to return JSON.Net:
This works a treat
Annoying, isn't it ?
My solution was to change my WCF service to get it to return DateTimes in a more readable (non-Microsoft) format. Notice below, the "UpdateDateOriginal", which is WCF's default format of dates, and my "UpdateDate", which is formatted to something more readable.
Here's how to do it:
Changing WCF date format
Hope this helps.
I had a number of issues come up with JSON dates and decided to just get rid of the problem by addressing the date issue in the SQL. Change the date format to a string format
select flddate from tblName
select flddate, convert(varchar(12), flddate, 113) as fldDateStr from tblName
By using the fldDateStr the problem dissappeared and I could still use the date field for sorting or other purposes.
It returns Server Date Format. You need to define your own function.
function jsonDateFormat(jsonDate) {
// Changed data format;
return (new Date(parseInt(jsonDate.substr(6)))).format("mm-dd-yyyy / h:MM tt");
};
0
In your cshtml,
<tr ng-repeat="value in Results">
<td>{{value.FileReceivedOn | mydate | date : 'dd-MM-yyyy'}} </td>
</tr>
In Your JS File, maybe app.js,
Outside of app.controller, add the below filter.
Here the "mydate" is the function which you are calling for parsing the date. Here the "app" is the variable which contains the angular.module
app.filter("mydate", function () {
var re = /\/Date\(([0-9]*)\)\//;
return function (x) {
var m = x.match(re);
if (m) return new Date(parseInt(m[1]));
else return null;
};
});
The easiest one:
var milisegundos = parseInt(data.replace("/Date(", "").replace(")/", ""));
Var newDate = new Date(milisegundos).toLocaleDateString("en-UE");

Populating empty elements of a column in a list

Please refer to this sample data:
# |IDNum |Date |data |SomeDate |TranCode
1|888888| 12/16/10|aaaaa| |a10
2|888888| 12/16/10|bbbbb| 11/16/15|a8
3|888888| 12/16/10|ccccc| |a11
4|888888| 11/16/10|aaaaa| |a6
5|888888| 11/16/10|bbbbb| |a5
6|888888| 11/16/10|ccccc| 10/16/15|a9
7|888888| 11/16/10|aaaaa| |a11
8|888888| 11/15/10|bbbbb| |a3
9|888888| 10/16/10|ccccc| |a6
10|888888| 10/16/10|aaaaa| |a5
11|888888| 10/16/10|bbbbb| 09/16/15|a9
12|888888| 10/16/10|ccccc| |a11
13|888888| 09/16/10|aaaaa| |a6
14|888888| 09/16/10|bbbbb| 08/16/15|a5
15|888888| 09/16/10|ccccc| |a9
16|111111| 03/02/15|aaaaa| |a9
17|111111| 02/27/15|bbbbb| 12/01/15|a6
18|111111| 02/10/15|ccccc| |a1
19|111111| 02/01/15|aaaaa| |a10
20|111111| 02/01/15|bbbbb| 11/01/15|a9
21|111111| 01/05/15|ccccc| |a10
22|111111| 01/05/15|aaaaa| 10/01/15|a9
23|111111| 12/31/14|bbbbb| |a12
24|111111| 12/30/14|ccccc| |a2
25|111111| 12/01/14|aaaaa| |a6
26|111111| 12/01/14|bbbbb| 10/01/15|a10
I have the above data stored as a list delimited by pipes and sorted by Date descending. I would need the "SomeDate" field to populate using the last date available in the row for that particular IDNumber.
So for example:
Row 1 should show a date of 11/16/15.
Row 3:5 should show a date of 10/16/15.
Row 7:10 should show a date of 09/16/15
Row 15 should show no date since there is no preceding date for that IDNum.
Row 16 should show a date of 12/01/15
Any logic recommendations would be much appreciated.
EDIT: To clarify - The data posted above is currently stored in a list. What I need help with is coming up with logic of how to solve my problem.
Here is a full writeup of how to solve this issue. Note that I put the sample data into C:\test\sample.txt for ease of use.
public class FileData
{
public string ID { get; set; }
public string IDNum { get; set; }
public string Date { get; set; }
public string Data { get; set; }
public string SomeDate { get; set; }
public string TranCode { get; set; }
}
public class ReadFile
{
public string SampleFile = #"C:\test\sample.txt";
public ReadFile()
{
StreamReader reader = new StreamReader(SampleFile);
string sampleFile = reader.ReadToEnd();
reader.Close();
string[] lines = sampleFile.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
string previousDate = "";
List<FileData> fileDatas = new List<FileData>();
for (int i = lines.Length - 1; i >= 0; i--)
{
FileData data = new FileData();
string[] columns = lines[i].Split('|');
data.ID = columns[0].Trim();
data.IDNum = columns[1].Trim();
data.Date = columns[2].Trim();
data.Data = columns[3].Trim();
string someDate = columns[4].Trim();
if (someDate.Equals(""))
{
data.SomeDate = previousDate;
}
else
{
previousDate = someDate;
data.SomeDate = someDate;
}
data.TranCode = columns[5].Trim();
fileDatas.Add(data);
}
}
}
Please notice that I created a "FileData" class to use to store the values.
Also notice that I am going through this data backwards, as it's easier to assign the dates this way.
What this does:
This reads all the data from the file into a string. That string is then split by line ends (\r\n).
Once you have a list of lines, we go BACKWARDS through it (int i = lines.length - 1; i < 0; i--).
Going backwards, we simply assign data, except for the "somedate" column. Here we check to see if somedate has a value. If it does, we assign a "previousDate" variable that value, and then assign the value. If it doesn't have a value, we use the value from previousDate. This ensures it will change appropriately.
The one issue with this is actually a potential issue with the data. If the end of the file does not have a date, you will have blank values for the SomeDate column until the first time you encounter a date.
Compiled, tested, and working.

How to apply Generics methods

I'm using FileHelper.dll for converting list into csv files and it is working perfectly.
Totally I'm having 9 Lists and corresponding 9 methods to handle file conversion and it will grow in future
Here,I have showed only 3 methods.
//-----Transaction.csv
public DateTime ExportResultsToCsv(string filePath, string HeaderLine, List<RetailTransaction> retailTxnList)
{
engine = new FileHelperEngine(typeof(RetailTransaction)) { HeaderText = HeaderLine };
engine.WriteFile(filePath, retailTxnList);
return DateTime.Now;
}
//-----ConcessionSale.csv
public DateTime ExportResultsToCsv(string filePath, string HeaderLine, List<ConcessionSale> concessionSaleList)
{
engine = new FileHelperEngine(typeof(ConcessionSale)) { HeaderText = HeaderLine };
engine.WriteFile(filePath, concessionSaleList);
return DateTime.Now;
}
//-----MerchandiseSale.csv
public DateTime ExportResultsToCsv(string filePath, string HeaderLine, List<MerchandiseSale> merchandiseSaleList)
{
engine = new FileHelperEngine(typeof(MerchandiseSale)) { HeaderText = HeaderLine };
engine.WriteFile(filePath, merchandiseSaleList);
return DateTime.Now;
}
While Googling, I read some concepts in Generics however I'm not able to get an idea. My concern, it is possible to use Generics here. Like having one generic method instead of many method like above.
Please shed some light on this issue. Is it possible to reduce the number of methods?
Thanks in advance.
public DateTime ExportResultsToCsv<T>(string filePath, string HeaderLine, List<T> data)
{
engine = new FileHelperEngine(typeof(T)) { HeaderText = HeaderLine };
engine.WriteFile(filePath, data);
return DateTime.Now;
}
For more info on generics see this article on MSDN
This is a situation where you can use generics. You would use a type variable, usually T is used so that is why you commonly see it. This variable will replace the type of your list. As a result, you will need to pass the list type when calling the method
public DateTime ExportResultsToCsv<T>(string filePath, string HeaderLine, List<T> SaleList)
{
engine = new FileHelperEngine(typeof(T)) { HeaderText = HeaderLine };
engine.WriteFile(filePath, SaleList);
return DateTime.Now;
}
and then you could simply call it like this:
ExportResultsToCsv(filePath,Header,salesList)

Need help formulating regular expression to parse data

Basically,
I have text I want to spit out from a block of text. I have the regular expression down for the most part however, It's either too little[skips a section] or too much[reads part of the next section].It basically needs to read text that I extracted from a bank statement.I already tried reading up on regular expressions more, however I still have no clue as to what to do.
Heres a bit of a sample for you guys to understand what I'm trying to do.
_4XXXXXXXXXXXXXX9_
_SOU THE HOME DEPOT 431 POMPANO BEACH * FL
AUT 020112 DDA PURCHASE_
_2/1_DEBIT POS_3.15_
The underscores are basically parts I want to extract. Basically everything except the DEBIT POS basically.
And the regex I'm using is:
\A
(?<SerialNumber>\b[0-9]{13,16}\b)
(?<Description>.) 'PROBLEM HERE'
(?<PostingDate>
(?:1[0-2]|[1-9])/(?:3[01]|[12][0-9]|[1-9]))
(?<Amount>[,0-9]+\.[0-9]{2})
\Z
I cant set the Description to be from any length of characters because I don't know the maximum length that the text portion will be. I also don't know if it's 2 lines for description or just 1. Thats mainly whats confusing me.
I imagine you want to join every four lines together as one line first:
var file = #"C:\temp.txt";
var lines = System.IO.File.ReadAllLines(file);
var buffer = new List<String>();
for (var i = 0; i < lines.Length; i++ )
{
if (i % 4 == 0) { buffer.Add(""); }
buffer[buffer.Count - 1] += lines[i] + " ";
}
buffer.ForEach(b => Console.WriteLine(b));
Then you can actually parse each entry in buffer as if it's one line. This can be done easily using either regex or just string Substrings. Far easier than trying to do it across lines.
The above code isn't the cleanest, but it works.
Look like another simple answer of don't use Regex. If each of these are lines, it wouldn't be that hard to File.ReadAllLines() and parse each line.
public class Order
{
public string SerialNumber { get; set; }
public string Description { get; set; }
public DateTime PostingDate { get; set; }
public Decimal Amount { get; set; }
public void SetSerialNumberFromRaw(string serialNumber)
{
// Convert to required type, etc.
this.SerialNumber = <someConvertedValue>;
}
public void <OtherNeededValueConverters>
}
List<string> lines = File.ReadAlllines("<filename").ToList();
List<Order> orders = new List<Order>();
Order currentOrder = null;
foreach (string line in lines)
{
if (currentOrder = null)
{
currentOrder = new Order();
orders.Add(currentOrder);
currentOrder.SetSerialNumberFromRaw(line);
}
else
{
if (line.Contains("DEBIT POS", CultureInfo.CurrentCultureIngoreCase))
{
currentOrder.SetPostingDateAndAmount(line);
currentOrder = null;
}
else
{
currentOrder.SetAppendDescription(line);
}
}
}

Categories

Resources