diff --git a/config/environments/development.rb b/config/environments/development.rb
index 8bec9789c..3b894d207 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -7,11 +7,11 @@ RedmineApp::Application.configure do
# Log error messages when you accidentally call methods on nil.
config.whiny_nils = true
-
+ config.logger = Logger.new('log/development.log', 'daily') # daily, weekly or monthly
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
-
+ config.cache_store = :file_store, "#{Rails.root }/public/tmp/"
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = true
diff --git a/config/environments/production.rb b/config/environments/production.rb
index ab4cd4011..48b2514cf 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -17,8 +17,9 @@ RedmineApp::Application.configure do
# config.logger.level = Logger::INFO
# Full error reports are disabled and caching is turned on
+ config.logger = Logger.new('log/production.log', 'daily',1048576) # daily, weekly or monthly
config.action_controller.perform_caching = true
-
+ config.cache_store = :file_store, "#{Rails.root }/public/tmp/"
# Enable serving of images, stylesheets, and javascripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"
diff --git a/config/initializers/logger.rb b/config/initializers/logger.rb
new file mode 100644
index 000000000..e9b61ce06
--- /dev/null
+++ b/config/initializers/logger.rb
@@ -0,0 +1,229 @@
+# logger.rb - simple logging utility
+# Copyright (C) 2000-2003, 2005, 2008, 2011 NAKAMURA, Hiroshi .
+#
+# Documentation:: NAKAMURA, Hiroshi and Gavin Sinclair
+# License::
+# You can redistribute it and/or modify it under the same terms of Ruby's
+# license; either the dual license version in 2003, or any later version.
+# Revision:: $Id: logger.rb 31641 2011-05-19 00:07:25Z nobu $
+#
+# A simple system for logging messages. See Logger for more documentation.
+
+require 'monitor'
+require 'fileutils'
+# == Description
+#
+# The Logger class provides a simple but sophisticated logging utility that
+# you can use to output messages.
+#
+# The messages have associated levels, such as +INFO+ or +ERROR+ that indicate
+# their importance. You can then give the Logger a level, and only messages
+# at that level of higher will be printed.
+#
+# The levels are:
+#
+# +FATAL+:: an unhandleable error that results in a program crash
+# +ERROR+:: a handleable error condition
+# +WARN+:: a warning
+# +INFO+:: generic (useful) information about system operation
+# +DEBUG+:: low-level information for developers
+#
+# For instance, in a production system, you may have your Logger set to
+# +INFO+ or even +WARN+
+# When you are developing the system, however, you probably
+# want to know about the program's internal state, and would set the Logger to
+# +DEBUG+.
+#
+# *Note*: Logger does not escape or sanitize any messages passed to it.
+# Developers should be aware of when potentially malicious data (user-input)
+# is passed to Logger, and manually escape the untrusted data:
+#
+# logger.info("User-input: #{input.dump}")
+# logger.info("User-input: %p" % input)
+#
+# You can use #formatter= for escaping all data.
+#
+# original_formatter = Logger::Formatter.new
+# logger.formatter = proc { |severity, datetime, progname, msg|
+# original_formatter.call(severity, datetime, progname, msg.dump)
+# }
+# logger.info(input)
+#
+# === Example
+#
+# This creates a logger to the standard output stream, with a level of +WARN+
+#
+# log = Logger.new(STDOUT)
+# log.level = Logger::WARN
+#
+# log.debug("Created logger")
+# log.info("Program started")
+# log.warn("Nothing to do!")
+#
+# begin
+# File.each_line(path) do |line|
+# unless line =~ /^(\w+) = (.*)$/
+# log.error("Line in wrong format: #{line}")
+# end
+# end
+# rescue => err
+# log.fatal("Caught exception; exiting")
+# log.fatal(err)
+# end
+#
+# Because the Logger's level is set to +WARN+, only the warning, error, and
+# fatal messages are recorded. The debug and info messages are silently
+# discarded.
+#
+# === Features
+#
+# There are several interesting features that Logger provides, like
+# auto-rolling of log files, setting the format of log messages, and
+# specifying a program name in conjunction with the message. The next section
+# shows you how to achieve these things.
+#
+#
+# == HOWTOs
+#
+# === How to create a logger
+#
+# The options below give you various choices, in more or less increasing
+# complexity.
+#
+# 1. Create a logger which logs messages to STDERR/STDOUT.
+#
+# logger = Logger.new(STDERR)
+# logger = Logger.new(STDOUT)
+#
+# 2. Create a logger for the file which has the specified name.
+#
+# logger = Logger.new('logfile.log')
+#
+# 3. Create a logger for the specified file.
+#
+# file = File.open('foo.log', File::WRONLY | File::APPEND)
+# # To create new (and to remove old) logfile, add File::CREAT like;
+# # file = open('foo.log', File::WRONLY | File::APPEND | File::CREAT)
+# logger = Logger.new(file)
+#
+# 4. Create a logger which ages logfile once it reaches a certain size. Leave
+# 10 "old log files" and each file is about 1,024,000 bytes.
+#
+# logger = Logger.new('foo.log', 10, 1024000)
+#
+# 5. Create a logger which ages logfile daily/weekly/monthly.
+#
+# logger = Logger.new('foo.log', 'daily')
+# logger = Logger.new('foo.log', 'weekly')
+# logger = Logger.new('foo.log', 'monthly')
+#
+# === How to log a message
+#
+# Notice the different methods (+fatal+, +error+, +info+) being used to log
+# messages of various levels? Other methods in this family are +warn+ and
+# +debug+. +add+ is used below to log a message of an arbitrary (perhaps
+# dynamic) level.
+#
+# 1. Message in block.
+#
+# logger.fatal { "Argument 'foo' not given." }
+#
+# 2. Message as a string.
+#
+# logger.error "Argument #{ @foo } mismatch."
+#
+# 3. With progname.
+#
+# logger.info('initialize') { "Initializing..." }
+#
+# 4. With severity.
+#
+# logger.add(Logger::FATAL) { 'Fatal error!' }
+#
+# The block form allows you to create potentially complex log messages,
+# but to delay their evaluation until and unless the message is
+# logged. For example, if we have the following:
+#
+# logger.debug { "This is a " + potentially + " expensive operation" }
+#
+# If the logger's level is +INFO+ or higher, no debug messages will be logged,
+# and the entire block will not even be evaluated. Compare to this:
+#
+# logger.debug("This is a " + potentially + " expensive operation")
+#
+# Here, the string concatenation is done every time, even if the log
+# level is not set to show the debug message.
+#
+# === How to close a logger
+#
+# logger.close
+#
+# === Setting severity threshold
+#
+# 1. Original interface.
+#
+# logger.sev_threshold = Logger::WARN
+#
+# 2. Log4r (somewhat) compatible interface.
+#
+# logger.level = Logger::INFO
+#
+# DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
+#
+#
+# == Format
+#
+# Log messages are rendered in the output stream in a certain format by
+# default. The default format and a sample are shown below:
+#
+# Log format:
+# SeverityID, [Date Time mSec #pid] SeverityLabel -- ProgName: message
+#
+# Log sample:
+# I, [Wed Mar 03 02:34:24 JST 1999 895701 #19074] INFO -- Main: info.
+#
+# You may change the date and time format via #datetime_format=
+#
+# logger.datetime_format = "%Y-%m-%d %H:%M:%S"
+# # e.g. "2004-01-03 00:54:26"
+#
+# Or, you may change the overall format with #formatter= method.
+#
+# logger.formatter = proc do |severity, datetime, progname, msg|
+# "#{datetime}: #{msg}\n"
+# end
+# # e.g. "Thu Sep 22 08:51:08 GMT+9:00 2005: hello world"
+#
+class Logger
+ #具体内容请看https://bugs.ruby-lang.org/issues/7303
+ # Device used for logging messages.
+ class LogDevice
+ def shift_log_period(period_end)
+ postfix = period_end.strftime("%Y%m%d") # YYYYMMDD
+ age_file = "#{@filename}.#{postfix}"
+ if FileTest.exist?(age_file)
+ # try to avoid filename crash caused by Timestamp change.
+ idx = 0
+ # .99 can be overridden; avoid too much file search with 'loop do'
+ while idx < 100
+ idx += 1
+ age_file = "#{@filename}.#{postfix}.#{idx}"
+ break unless FileTest.exist?(age_file)
+ end
+ end
+ # @dev.close rescue nil
+ # File.rename("#{@filename}", age_file)
+ # @dev = create_logfile(@filename)
+ #覆盖原来lib库的方法,将上边三行删除,增加下边两行
+ FileUtils.cp(@filename, age_file)
+ reset_logfile(@dev) # see below for this new method return true
+ return true
+ end
+ #打开原来lib库,新增一个方法
+ def reset_logfile(logdev)
+ logdev.truncate( 0 )
+ logdev.sync = true
+ add_log_header(logdev)
+ end
+ end
+end
diff --git a/config/locales/zh.yml b/config/locales/zh.yml
index d058a6c1b..a33b967a0 100644
--- a/config/locales/zh.yml
+++ b/config/locales/zh.yml
@@ -2310,6 +2310,31 @@ zh:
label_poll_answer_valid_result: 以上为有效问答题答案!
label_answer_total: 总计:
label_join_project: 加入项目
-
label_technical_support: 技术支持:
label_feedback: 意见反馈
+ label_log_detail: "日志详情"
+ label_log_delete_log: "删除日志"
+ label_log_access_analysis: "访问统计"
+ label_log_time_analysis: "耗时分析"
+ label_log_refresh: "刷新"
+ label_log_key: "关键字:"
+ label_log_time: "时间:"
+ label_log_delete_confirm: "确认清除该天日志内容?"
+ label_log_access_count: "访问次数"
+ label_log_url: "URL路径"
+ label_log_ip: "访问IP"
+ label_log_access_time: "访问时间"
+ label_log_access_controller_action: "模块路径"
+ label_log_response_time: "响应时间"
+ label_log_views_time: "页面渲染时间"
+ label_log_views_time_percent: "页面渲染时间百分比"
+ label_log_active_record_time: "AR响应时间"
+ label_log_active_record_time_percent: "AR响应时间百分比"
+ views:
+ pagination:
+ first: "« 首页"
+ last: "末页 »"
+ previous: "« 上一页"
+ next: "下一页 »"
+ truncate: "..."
+
diff --git a/config/newrelic.yml b/config/newrelic.yml
new file mode 100644
index 000000000..df431805d
--- /dev/null
+++ b/config/newrelic.yml
@@ -0,0 +1,224 @@
+#
+# This file configures the New Relic Agent. New Relic monitors Ruby, Java,
+# .NET, PHP, Python and Node applications with deep visibility and low
+# overhead. For more information, visit www.newrelic.com.
+#
+# Generated January 23, 2015
+#
+# This configuration file is custom generated for Trustie
+
+
+# Here are the settings that are common to all environments
+common: &default_settings
+ # ============================== LICENSE KEY ===============================
+
+ # You must specify the license key associated with your New Relic
+ # account. This key binds your Agent's data to your account in the
+ # New Relic service.
+ license_key: '9b481f5c9ec07de722dcaaa17b38d0d1efff32c0'
+
+ # Agent Enabled (Ruby/Rails Only)
+ # Use this setting to force the agent to run or not run.
+ # Default is 'auto' which means the agent will install and run only
+ # if a valid dispatcher such as Mongrel is running. This prevents
+ # it from running with Rake or the console. Set to false to
+ # completely turn the agent off regardless of the other settings.
+ # Valid values are true, false and auto.
+ #
+ # agent_enabled: auto
+
+ # Application Name Set this to be the name of your application as
+ # you'd like it show up in New Relic. The service will then auto-map
+ # instances of your application into an "application" on your
+ # dashboard page. If you want to map this instance into multiple
+ # apps, like "AJAX Requests" and "All UI" then specify a semicolon
+ # separated list of up to three distinct names, or a yaml list.
+ # Defaults to the capitalized RAILS_ENV or RACK_ENV (i.e.,
+ # Production, Staging, etc)
+ #
+ # Example:
+ #
+ # app_name:
+ # - Ajax Service
+ # - All Services
+ #
+ # Caution: If you change this name, a new application will appear in the New
+ # Relic user interface with the new name, and data will stop reporting to the
+ # app with the old name.
+ #
+ # See https://newrelic.com/docs/site/renaming-applications for more details
+ # on renaming your New Relic applications.
+ #
+ app_name: My Application
+
+ # When "true", the agent collects performance data about your
+ # application and reports this data to the New Relic service at
+ # newrelic.com. This global switch is normally overridden for each
+ # environment below. (formerly called 'enabled')
+ monitor_mode: true
+
+ # Developer mode should be off in every environment but
+ # development as it has very high overhead in memory.
+ developer_mode: false
+
+ # The newrelic agent generates its own log file to keep its logging
+ # information separate from that of your application. Specify its
+ # log level here.
+ log_level: info
+
+ # Optionally set the path to the log file This is expanded from the
+ # root directory (may be relative or absolute, e.g. 'log/' or
+ # '/var/log/') The agent will attempt to create this directory if it
+ # does not exist.
+ # log_file_path: 'log'
+
+ # Optionally set the name of the log file, defaults to 'newrelic_agent.log'
+ # log_file_name: 'newrelic_agent.log'
+
+ # The newrelic agent communicates with the service via https by default. This
+ # prevents eavesdropping on the performance metrics transmitted by the agent.
+ # The encryption required by SSL introduces a nominal amount of CPU overhead,
+ # which is performed asynchronously in a background thread. If you'd prefer
+ # to send your metrics over http uncomment the following line.
+ # ssl: false
+
+ #============================== Browser Monitoring ===============================
+ # New Relic Real User Monitoring gives you insight into the performance real users are
+ # experiencing with your website. This is accomplished by measuring the time it takes for
+ # your users' browsers to download and render your web pages by injecting a small amount
+ # of JavaScript code into the header and footer of each page.
+ browser_monitoring:
+ # By default the agent automatically injects the monitoring JavaScript
+ # into web pages. Set this attribute to false to turn off this behavior.
+ auto_instrument: true
+
+ # Proxy settings for connecting to the New Relic server.
+ #
+ # If a proxy is used, the host setting is required. Other settings
+ # are optional. Default port is 8080.
+ #
+ # proxy_host: hostname
+ # proxy_port: 8080
+ # proxy_user:
+ # proxy_pass:
+
+ # The agent can optionally log all data it sends to New Relic servers to a
+ # separate log file for human inspection and auditing purposes. To enable this
+ # feature, change 'enabled' below to true.
+ # See: https://newrelic.com/docs/ruby/audit-log
+ audit_log:
+ enabled: false
+
+ # Tells transaction tracer and error collector (when enabled)
+ # whether or not to capture HTTP params. When true, frameworks can
+ # exclude HTTP parameters from being captured.
+ # Rails: the RoR filter_parameter_logging excludes parameters
+ # Java: create a config setting called "ignored_params" and set it to
+ # a comma separated list of HTTP parameter names.
+ # ex: ignored_params: credit_card, ssn, password
+ capture_params: false
+
+ # Transaction tracer captures deep information about slow
+ # transactions and sends this to the New Relic service once a
+ # minute. Included in the transaction is the exact call sequence of
+ # the transactions including any SQL statements issued.
+ transaction_tracer:
+
+ # Transaction tracer is enabled by default. Set this to false to
+ # turn it off. This feature is only available at the Professional
+ # and above product levels.
+ enabled: true
+
+ # Threshold in seconds for when to collect a transaction
+ # trace. When the response time of a controller action exceeds
+ # this threshold, a transaction trace will be recorded and sent to
+ # New Relic. Valid values are any float value, or (default) "apdex_f",
+ # which will use the threshold for an dissatisfying Apdex
+ # controller action - four times the Apdex T value.
+ transaction_threshold: apdex_f
+
+ # When transaction tracer is on, SQL statements can optionally be
+ # recorded. The recorder has three modes, "off" which sends no
+ # SQL, "raw" which sends the SQL statement in its original form,
+ # and "obfuscated", which strips out numeric and string literals.
+ record_sql: obfuscated
+
+ # Threshold in seconds for when to collect stack trace for a SQL
+ # call. In other words, when SQL statements exceed this threshold,
+ # then capture and send to New Relic the current stack trace. This is
+ # helpful for pinpointing where long SQL calls originate from.
+ stack_trace_threshold: 0.500
+
+ # Determines whether the agent will capture query plans for slow
+ # SQL queries. Only supported in mysql and postgres. Should be
+ # set to false when using other adapters.
+ # explain_enabled: true
+
+ # Threshold for query execution time below which query plans will
+ # not be captured. Relevant only when `explain_enabled` is true.
+ # explain_threshold: 0.5
+
+ # Error collector captures information about uncaught exceptions and
+ # sends them to New Relic for viewing
+ error_collector:
+
+ # Error collector is enabled by default. Set this to false to turn
+ # it off. This feature is only available at the Professional and above
+ # product levels.
+ enabled: true
+
+ # To stop specific errors from reporting to New Relic, set this property
+ # to comma-separated values. Default is to ignore routing errors,
+ # which are how 404's get triggered.
+ ignore_errors: "ActionController::RoutingError,Sinatra::NotFound"
+
+ # If you're interested in capturing memcache keys as though they
+ # were SQL uncomment this flag. Note that this does increase
+ # overhead slightly on every memcached call, and can have security
+ # implications if your memcached keys are sensitive
+ # capture_memcache_keys: true
+
+# Application Environments
+# ------------------------------------------
+# Environment-specific settings are in this section.
+# For Rails applications, RAILS_ENV is used to determine the environment.
+# For Java applications, pass -Dnewrelic.environment to set
+# the environment.
+
+# NOTE if your application has other named environments, you should
+# provide newrelic configuration settings for these environments here.
+
+development:
+ <<: *default_settings
+ # Turn on communication to New Relic service in development mode
+ monitor_mode: true
+ app_name: My Application (Development)
+
+ # Rails Only - when running in Developer Mode, the New Relic Agent will
+ # present performance information on the last 100 transactions you have
+ # executed since starting the mongrel.
+ # NOTE: There is substantial overhead when running in developer mode.
+ # Do not use for production or load testing.
+ developer_mode: true
+
+test:
+ <<: *default_settings
+ # It almost never makes sense to turn on the agent when running
+ # unit, functional or integration tests or the like.
+ monitor_mode: false
+
+# Turn on the agent in production for 24x7 monitoring. NewRelic
+# testing shows an average performance impact of < 5 ms per
+# transaction, you can leave this on all the time without
+# incurring any user-visible performance degradation.
+production:
+ <<: *default_settings
+ monitor_mode: true
+
+# Many applications have a staging environment which behaves
+# identically to production. Support for that environment is provided
+# here. By default, the staging environment has the agent turned on.
+staging:
+ <<: *default_settings
+ monitor_mode: true
+ app_name: My Application (Staging)
diff --git a/config/routes.rb b/config/routes.rb
index 122481d38..755ce6c29 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -26,6 +26,8 @@
# Example: :via => :get ====> :via => :get
RedmineApp::Application.routes.draw do
+
+
#match '/contests/:id/contestnotifications', :controller => 'contestnotifications', :action => 'index'
mount Mobile::API => '/api'
@@ -841,6 +843,14 @@ RedmineApp::Application.routes.draw do
match 'words/add_brief_introdution'
+ ##added by lizanle 日志查看路由
+ match 'system_log/index'
+ match 'system_log/access_analysis'
+ match 'system_log/time_analysis'
+ match "/system_log" ,:to => 'system_log#index'
+ match 'system_log/clear'
+ ##ended by lizanle
+
Dir.glob File.expand_path("plugins/*", Rails.root) do |plugin_dir|
file = File.join(plugin_dir, "config/routes.rb")
diff --git a/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb b/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb
index 17f834c84..f4712fa3e 100644
--- a/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb
+++ b/lib/plugins/acts_as_activity_provider/lib/acts_as_activity_provider.rb
@@ -49,8 +49,11 @@ module Redmine
end
module ClassMethods
+ # Time 2015-01-27 16:30:47
+ # Author lizanle
+ # Description 用原来的写法from,to更加容易懂
# Returns events of type event_type visible by user that occured between from and to
- def find_events(event_type, user, days, created_time, options)
+ def find_events(event_type, user, from, to, options)
provider_options = activity_provider_options[event_type]
raise "#{self.name} can not provide #{event_type} events." if provider_options.nil?
@@ -91,17 +94,18 @@ module Redmine
ActiveSupport::Deprecation.warn "acts_as_activity_provider with implicit :permission option is deprecated. Add a visible scope to the #{self.name} model or use explicit :permission option."
scope = scope.scoped(:conditions => Project.allowed_to_condition(user, "view_#{self.name.underscore.pluralize}".to_sym, options))
end
- unless scope.all(provider_options[:find_options].dup).first.nil?
+ # Time 2015-01-27 15:18:33
+ # Author lizanle
+ # Description 删除 unless scope.all,因为这个执行查询,并且没有加入时间限制,与下边 scope.all(provider_options[:find_options].dup)重复
+ if options[:course]
if provider_options[:timestamp].include? "updated_on"
to = scope.scoped(:order => "#{provider_options[:timestamp]} desc").all(provider_options[:find_options].dup).first.updated_on
else
to = scope.scoped(:order => "#{provider_options[:timestamp]} desc").all(provider_options[:find_options].dup).first.created_on
end
- if options[:course]
from = (to - days.days) > created_time ? (to - days.days) : created_time.to_date
- else
- from = to - days.days - 1.years
- end
+ else
+ #from = to - Setting.activity_days_default.to_i
end
if from && to
diff --git a/lib/plugins/acts_as_event/lib/acts_as_event.rb b/lib/plugins/acts_as_event/lib/acts_as_event.rb
index e323c2b3e..42673cde7 100644
--- a/lib/plugins/acts_as_event/lib/acts_as_event.rb
+++ b/lib/plugins/acts_as_event/lib/acts_as_event.rb
@@ -43,6 +43,7 @@ module Redmine
base.extend ClassMethods
end
+
%w(datetime title description author type).each do |attr|
src = <<-END_SRC
def event_#{attr}
diff --git a/lib/redmine/activity/fetcher.rb b/lib/redmine/activity/fetcher.rb
index b3f473893..c4adc6adb 100644
--- a/lib/redmine/activity/fetcher.rb
+++ b/lib/redmine/activity/fetcher.rb
@@ -77,9 +77,12 @@ module Redmine
@scope = Redmine::Activity.default_event_types
end
+ # Time 2015-01-27 16:31:58
+ # Author lizanle
+ # Description 用from to 更加浅显易懂
# Returns an array of events for the given date range
# sorted in reverse chronological order
- def events(days = nil, created_time = nil, options={})
+ def events(from = nil, to = nil, options={})
e = []
@options[:limit] = options[:limit]
# modify by nwb
@@ -87,7 +90,7 @@ module Redmine
@scope.each do |event_type|
constantized_providers(event_type).each do |provider|
- e += provider.find_events(event_type, @user, days, created_time, @options)
+ e += provider.find_events(event_type, @user, from, to, @options)
end
end
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index 1dedc1b8c..5692ebe83 100644
--- a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -685,3 +685,165 @@ function PrecentChange(obj){
$("select[id='issue_status_id']").find("option[value='2']").attr("selected","selected");
}
}
+
+//added by lizanle 日期選擇js
+function HS_DateAdd(interval,number,date){
+ number = parseInt(number);
+ if (typeof(date)=="string"){var date = new Date(date.split("-")[0],date.split("-")[1],date.split("-")[2])}
+ if (typeof(date)=="object"){var date = date}
+ switch(interval){
+ case "y":return new Date(date.getFullYear()+number,date.getMonth(),date.getDate()); break;
+ case "m":return new Date(date.getFullYear(),date.getMonth()+number,checkDate(date.getFullYear(),date.getMonth()+number,date.getDate())); break;
+ case "d":return new Date(date.getFullYear(),date.getMonth(),date.getDate()+number); break;
+ case "w":return new Date(date.getFullYear(),date.getMonth(),7*number+date.getDate()); break;
+ }
+}
+function checkDate(year,month,date){
+ var enddate = ["31","28","31","30","31","30","31","31","30","31","30","31"];
+ var returnDate = "";
+ if (year%4==0){enddate[1]="29"}
+ if (date>enddate[month]){returnDate = enddate[month]}else{returnDate = date}
+ return returnDate;
+}
+
+function WeekDay(date){
+ var theDate;
+ if (typeof(date)=="string"){theDate = new Date(date.split("-")[0],date.split("-")[1],date.split("-")[2]);}
+ if (typeof(date)=="object"){theDate = date}
+ return theDate.getDay();
+}
+function HS_calender(){
+ var lis = "";
+ var style = "";
+ /*可以把下面的css剪切出去独立一个css文件*/
+ style +="";
+
+ var now;
+ if (typeof(arguments[0])=="string"){
+ selectDate = arguments[0].split("-");
+ var year = selectDate[0];
+ var month = parseInt(selectDate[1])-1+"";
+ var date = selectDate[2];
+ now = new Date(year,month,date);
+ }else if (typeof(arguments[0])=="object"){
+ now = arguments[0];
+ }
+ var lastMonthEndDate = HS_DateAdd("d","-1",now.getFullYear()+"-"+now.getMonth()+"-01").getDate();
+ var lastMonthDate = WeekDay(now.getFullYear()+"-"+now.getMonth()+"-01");
+ var thisMonthLastDate = HS_DateAdd("d","-1",now.getFullYear()+"-"+(parseInt(now.getMonth())+1).toString()+"-01");
+ var thisMonthEndDate = thisMonthLastDate.getDate();
+ var thisMonthEndDay = thisMonthLastDate.getDay();
+ var todayObj = new Date();
+ today = todayObj.getFullYear()+"-"+todayObj.getMonth()+"-"+todayObj.getDate();
+
+ for (i=0; i" + lis;
+ lastMonthEndDate--;
+ }
+ for (i=1; i<=thisMonthEndDate; i++){ // Current Month's Date
+
+ if(today == now.getFullYear()+"-"+now.getMonth()+"-"+i){
+ var todayString = now.getFullYear()+"-"+(parseInt(now.getMonth())+1).toString()+"-"+i;
+ lis += "